2.0 自 1.7 以来的变更
使用 CachingConnectionFactory
从 2.0.2 版本开始,你可以配置 RabbitTemplate 使用与 listener 容器不同的连接。此变更可在 producer 因任何原因被阻塞时避免 consumer 死锁。更多信息参见使用单独连接。
AMQP Client 库
Spring AMQP 现在使用 RabbitMQ 团队提供的新版 5.0.x 版本 amqp-client 库。该客户端默认配置了自动恢复。参见RabbitMQ 自动连接/拓扑恢复。
从 4.0 版本开始,客户端默认启用自动恢复。虽然与该特性兼容,但 Spring AMQP 有自己的恢复机制,通常并不需要客户端的恢复特性。我们建议禁用 amqp-client 的自动恢复,以避免在 broker 可用但连接尚未恢复时出现 AutoRecoverConnectionNotCurrentlyOpenException。从 1.7.1 版本开始,除非你显式创建自己的 RabbitMQ 连接工厂并提供给 CachingConnectionFactory,否则 Spring AMQP 会禁用它。由 RabbitConnectionFactoryBean 创建的 RabbitMQ ConnectionFactory 实例默认也禁用了该选项。
通用变更
ExchangeBuilder 现在默认构建 durable exchange。在 @QeueueBinding 内使用的 @Exchange 注解也默认声明 durable exchange。在 @RabbitListener 内使用的 @Queue 注解,对于命名队列默认声明 durable 队列,对于匿名队列默认声明 non-durable 队列。更多信息参见队列与 Exchange 的 Builder API和注解驱动的 Listener 端点。
已删除的类
不再提供 UniquelyNameQueue。创建具有唯一名称的 durable、非 auto-delete 队列并不常见。此类已被删除。如果你需要其功能,请使用 new Queue(UUID.randomUUID().toString())。
新的 Listener 容器
在现有 SimpleMessageListenerContainer 之外新增了 DirectMessageListenerContainer。关于选择使用哪个容器以及如何配置它们,参见选择容器和消息 Listener 容器配置。
Log4j Appender
由于 log4j 已停止维护,该 appender 不再可用。关于可用的日志 appender,参见日志子系统 AMQP Appender。
RabbitTemplate 变更
此前,非事务性的 RabbitTemplate 如果运行在事务性 listener 容器线程上,会参与到已有的事务中。这是一个严重的 bug。不过,用户可能已经依赖了这一行为。从 1.6.2 版本开始,你必须在 template 上设置 channelTransacted 布尔值,它才会参与容器事务。
RabbitTemplate 现在(默认)使用 DirectReplyToMessageListenerContainer,而不是为每个请求创建一个新 consumer。更多信息参见RabbitMQ Direct reply-to。
AsyncRabbitTemplate 现在支持 direct reply-to。更多信息参见Async Rabbit Template。
RabbitTemplate 和 AsyncRabbitTemplate 现在有了接收 ParameterizedTypeReference<T> 参数的 receiveAndConvert 和 convertSendAndReceiveAsType 方法,让调用方指定将结果转换为何种类型。这对于复杂类型或消息头中未携带类型信息时特别有用。它需要 SmartMessageConverter,例如 Jackson2JsonMessageConverter。更多信息参见请求/回复消息传递、Async Rabbit Template、用 RabbitTemplate 从消息转换和用 RabbitTemplate 从消息转换。
现在可以使用 RabbitTemplate 在专用 channel 上执行多个操作。更多信息参见作用域操作。
Listener 适配器
提供了一个便捷的 FunctionalInterface,用于在 MessageListenerAdapter 中使用 lambda。更多信息参见MessageListenerAdapter。
Listener 容器变更
预取默认值
预取默认值过去为 1,这可能导致高效 consumer 利用不足。现在默认预取值为 250,在大多数常见场景下应能让 consumer 保持忙碌,从而提高吞吐量。
在某些场景下预取值应该设得较低——例如对于大消息,尤其是处理较慢时(消息可能在 client 进程中累积成大量内存),以及在需要严格消息顺序时(此时预取值应设回 1)。此外,对于低吞吐消息和多个 consumer(包括单个 listener 容器实例内的并发),你可能希望减小预取值,以使消息在各 consumer 之间分布更均匀。
关于预取的更多背景,参见这篇关于 RabbitMQ 中 consumer 利用率的文章,以及这篇关于排队论的文章。
消息数量
此前,对于容器发出的消息,MessageProperties.getMessageCount() 返回 0。此属性仅在使用 basicGet 时(例如来自 RabbitTemplate.receive() 方法)适用,现在对于容器消息初始化为 null。
事务回滚行为
现在事务回滚时的消息重新入队保持一致,而无论是否配置了事务管理器。更多信息参见关于已接收消息回滚的说明。
关闭行为
如果容器线程未在 shutdownTimeout 内响应关闭,则默认强制关闭 channel。更多信息参见消息 Listener 容器配置。
接收后消息后处理器
如果 afterReceiveMessagePostProcessors 属性中的某个 MessagePostProcessor 返回 null,则该消息被丢弃(并在适当时确认)。
连接工厂变更
连接和 channel 监听器接口现在提供一种获取异常信息的机制。更多信息参见连接与 Channel 监听器和发布是异步的——如何检测成功与失败。
现在提供新的 ConnectionNameStrategy,用于从 AbstractConnectionFactory 填充目标 RabbitMQ 连接的应用特定标识。更多信息参见连接与资源管理。
重试变更
不再提供 MissingMessageIdAdvice。其功能现在已内建。更多信息参见同步操作中的失败与重试选项。
匿名队列命名
默认情况下,AnonymousQueue 现在使用默认的 Base64UrlNamingStrategy 命名,而不是简单的 UUID 字符串。更多信息参见AnonymousQueue。
@RabbitListener 变更
现在可以在 @RabbitListener 注解中提供简单的队列声明(仅绑定到默认 exchange)。更多信息参见注解驱动的 Listener 端点。
现在可以配置 @RabbitListener 注解,使任何异常都返回给发送方。你也可以配置 RabbitListenerErrorHandler 来处理异常。更多信息参见处理异常。
使用 @QueueBinding 注解时,现在可以将一个队列绑定到多个 routing key。此外,@QueueBinding.exchange() 现在支持自定义 exchange 类型,并默认声明 durable exchange。
现在可以在注解级别设置 listener 容器的 concurrency,而无需为不同的并发设置配置不同的容器工厂。
现在可以在注解级别设置 listener 容器的 autoStartup 属性,覆盖容器工厂中的默认设置。
现在可以在 RabbitListener 容器工厂中设置接收后和发送(回复)前的 MessagePostProcessor 实例。
更多信息参见注解驱动的 Listener 端点。
从 2.0.3 版本开始,类级 @RabbitListener 上的其中一个 @RabbitHandler 注解可以被指定为默认。更多信息参见多方法 Listener。
容器条件回滚
使用外部事务管理器(例如 JDBC)时,现在在为容器提供事务属性的情况下支持基于规则的回滚。使用事务通知时也更加灵活。更多信息参见条件回滚。
移除 Jackson 1.x 支持
在早期版本中已废弃的 Jackson 1.x 转换器及相关组件现已删除。你可以使用基于 Jackson 2.x 的类似组件。更多信息参见Jackson2JsonMessageConverter。
JSON 消息转换器
当入站 JSON 消息的 _TypeId_ 被设为 Hashtable 时,默认转换类型现在为 LinkedHashMap。此前为 Hashtable。若要恢复为 Hashtable,可以在 DefaultClassMapper 上使用 setDefaultMapType。
XML 解析器
解析 Queue 和 Exchange XML 组件时,如果存在 id 属性,解析器不再将 name 属性值注册为 Bean 别名。更多信息参见关于 id 与 name 属性的说明。
阻塞连接
现在可以将 com.rabbitmq.client.BlockedListener 注入 org.springframework.amqp.rabbit.connection.Connection 对象。此外,当连接被 Broker 阻塞或解除阻塞时,ConnectionFactory 会发出 ConnectionBlockedEvent 和 ConnectionUnblockedEvent 事件。
更多信息参见连接与资源管理。