2.0 版本相对于 1.7 版本的变化

使用 CachingConnectionFactory

从 2.0.2 版本开始,您可以配置 RabbitTemplate 使用与监听器容器所用连接不同的连接。此更改可避免生产者因任何原因阻塞时消费者发生死锁。更多信息请参阅使用单独连接

AMQP 客户端库

Spring AMQP 现在使用 RabbitMQ 团队提供的新的 5.0.x 版本的 amqp-client 库。此客户端默认配置了自动恢复。更多信息请参阅RabbitMQ 自动连接/拓扑恢复

从 4.0 版本开始,客户端默认启用自动恢复。虽然与此功能兼容,但 Spring AMQP 有自己的恢复机制,通常不需要客户端的恢复功能。我们建议禁用 amqp-client 的自动恢复,以避免在 Broker 可用但连接尚未恢复时出现 AutoRecoverConnectionNotCurrentlyOpenException 实例。从 1.7.1 版本开始,Spring AMQP 会禁用它,除非您显式创建自己的 RabbitMQ 连接工厂并将其提供给 CachingConnectionFactory。由 RabbitConnectionFactoryBean 创建的 RabbitMQ ConnectionFactory 实例也默认禁用了此选项。

通用变更

ExchangeBuilder 现在默认构建持久化交换机。在 @QeueueBinding 中使用的 @Exchange 注解也默认声明持久化交换机。在 @RabbitListener 中使用的 @Queue 注解默认声明命名队列为持久化,匿名队列为非持久化。更多信息请参阅队列和交换机的 Builder API注解驱动的监听器端点

已删除的类

不再提供 UniquelyNameQueue。创建一个带有唯一名称的持久化非自动删除队列并不常见。此类已被删除。如果您需要其功能,请使用 new Queue(UUID.randomUUID().toString())

新的监听器容器

DirectMessageListenerContainer 已添加,与现有的 SimpleMessageListenerContainer 并存。有关如何选择和配置监听器容器的信息,请参阅选择容器消息监听器容器配置

Log4j Appender

由于 log4j 已结束生命周期,此 Appender 不再可用。有关可用日志 Appender 的信息,请参阅日志子系统 AMQP Appender

RabbitTemplate 变更

之前,非事务性的 RabbitTemplate 如果运行在事务性监听器容器线程上,就会参与现有的事务。这是一个严重 Bug。但是,用户可能依赖于这种行为。从 1.6.2 版本开始,您必须在模板上设置 channelTransacted boolean 属性,它才会参与容器事务。

RabbitTemplate 现在(默认情况下)使用 DirectReplyToMessageListenerContainer,而不是为每个请求创建一个新的消费者。更多信息请参阅RabbitMQ Direct reply-to

AsyncRabbitTemplate 现在支持 direct reply-to。更多信息请参阅异步 Rabbit 模板

RabbitTemplateAsyncRabbitTemplate 现在有了接受 ParameterizedTypeReference<T> 参数的 receiveAndConvertconvertSendAndReceiveAsType 方法,允许调用者指定结果的转换类型。这对于复杂类型或消息头中未传递类型信息的情况特别有用。它需要一个 SmartMessageConverter,例如 Jackson2JsonMessageConverter。更多信息请参阅请求/回复消息异步 Rabbit 模板以及使用 RabbitTemplateMessage 转换

您现在可以使用 RabbitTemplate 在专用通道上执行多个操作。更多信息请参阅作用域操作

监听器适配器

提供了一个方便的 FunctionalInterface,用于配合 MessageListenerAdapter 使用 Lambda 表达式。更多信息请参阅MessageListenerAdapter

监听器容器变更

Prefetch 默认值

Prefetch 的默认值以前是 1,这可能导致高效消费者的利用率不足。现在的默认 Prefetch 值是 250,这在大多数常见场景下应该能让消费者保持忙碌,从而提高吞吐量。

在某些场景下,Prefetch 值应设置得较低——例如,处理大型消息时(尤其是在处理速度较慢的情况下,消息可能会在客户端进程中累积大量内存),以及需要严格消息顺序时(在这种情况下,应将 Prefetch 值设置回 1)。此外,在消息量较低且有多个消费者(包括单个监听器容器实例内的并发)的情况下,您可能希望减少 Prefetch 值,以使消息在消费者之间更均匀地分布。

有关 Prefetch 的更多背景信息,请参阅这篇关于RabbitMQ 中消费者利用率的帖子,以及这篇关于排队论的帖子。

消息计数

之前,MessageProperties.getMessageCount() 对于容器发出的消息返回 0。此属性仅在使用 basicGet 时(例如,来自 RabbitTemplate.receive() 方法)适用,现在对于容器消息初始化为 null

事务回滚行为

事务回滚时的消息重新入队现在行为一致,无论是否配置了事务管理器。更多信息请参阅关于已接收消息回滚的注意事项

关闭行为

如果容器线程在 shutdownTimeout 内未响应关闭操作,通道默认会被强制关闭。更多信息请参阅消息监听器容器配置

接收后消息后处理器

如果在 afterReceiveMessagePostProcessors 属性中的 MessagePostProcessor 返回 null,则消息将被丢弃(并在适当情况下进行确认)。

连接工厂变更

连接和通道监听器接口现在提供了一种机制来获取关于异常的信息。更多信息请参阅连接和通道监听器以及发布是异步的 — 如何检测成功和失败

现在提供了一个新的 ConnectionNameStrategy,用于从 AbstractConnectionFactory 填充目标 RabbitMQ 连接的应用特定标识。更多信息请参阅连接与资源管理

重试变更

不再提供 MissingMessageIdAdvice。其功能现已内置。更多信息请参阅同步操作中的故障和重试选项

匿名队列命名

默认情况下,AnonymousQueues 现在使用默认的 Base64UrlNamingStrategy 进行命名,而不是简单的 UUID 字符串。更多信息请参阅AnonymousQueue

@RabbitListener 变更

您现在可以在 @RabbitListener 注解中提供简单的队列声明(仅绑定到默认交换机)。更多信息请参阅注解驱动的监听器端点

您现在可以配置 @RabbitListener 注解,以便将任何异常返回给发送方。您还可以配置一个 RabbitListenerErrorHandler 来处理异常。更多信息请参阅异常处理

您现在在使用 @QueueBinding 注解时,可以绑定具有多个路由键的队列。此外,@QueueBinding.exchange() 现在支持自定义交换机类型,并默认声明持久化交换机。

您现在可以在注解级别设置监听器容器的 concurrency,而无需为不同的并发设置配置不同的容器工厂。

您现在可以在注解级别设置监听器容器的 autoStartup 属性,覆盖容器工厂中的默认设置。

您现在可以在 RabbitListener 容器工厂中设置接收后和发送前(回复)的 MessagePostProcessor 实例。

更多信息请参阅注解驱动的监听器端点

从 2.0.3 版本开始,类级别 @RabbitListener 上的 @RabbitHandler 注解之一可以指定为默认处理方法。更多信息请参阅多方法监听器

容器条件回滚

在使用外部事务管理器(如 JDBC)时,如果为容器提供了事务属性,现在支持基于规则的回滚。在使用事务通知时,现在也更加灵活。更多信息请参阅条件回滚

移除 Jackson 1.x 支持

在之前的版本中已弃用,Jackson 1.x 转换器及相关组件现已删除。您可以使用基于 Jackson 2.x 的类似组件。更多信息请参阅Jackson2JsonMessageConverter

JSON 消息转换器

当入站 JSON 消息的 TypeId 设置为 Hashtable 时,默认转换类型现在是 LinkedHashMap。以前是 Hashtable。要恢复为 Hashtable,您可以在 DefaultClassMapper 上使用 setDefaultMapType

XML 解析器

解析 QueueExchange XML 组件时,如果存在 id 属性,解析器不再将 name 属性值注册为 Bean 别名。更多信息请参阅关于 idname 属性的注意事项

阻塞连接

您现在可以将 com.rabbitmq.client.BlockedListener 注入到 org.springframework.amqp.rabbit.connection.Connection 对象中。此外,当 Broker 阻塞或解除阻塞连接时,ConnectionFactory 会发出 ConnectionBlockedEventConnectionUnblockedEvent 事件。

更多信息请参阅连接与资源管理