2.0 版本相对于 1.7 版本的变更
使用 CachingConnectionFactory
从 2.0.2 版本开始,你可以配置 RabbitTemplate 使用与监听器容器不同的连接。这一改动避免了当生产者因任何原因被阻塞时消费者出现死锁的情况。更多信息请参阅使用独立连接。
AMQP 客户端库
Spring AMQP 现在使用由 RabbitMQ 团队提供的 amqp-client 库的 5.0.x 新版本。该客户端默认配置了自动恢复功能。详情请参阅 RabbitMQ 自动连接/拓扑恢复。
从 4.0 版本开始,客户端默认启用了自动恢复功能。虽然 Spring AMQP 与此功能兼容,但它有自己的恢复机制,通常不需要使用客户端的恢复功能。我们建议你禁用 amqp-client 的自动恢复功能,以避免在代理可用但连接尚未恢复时出现 AutoRecoverConnectionNotCurrentlyOpenException 异常。从 1.7.1 版本开始,Spring AMQP 会默认禁用此功能,除非你显式创建自己的 RabbitMQ 连接工厂并将其提供给 CachingConnectionFactory。由 RabbitConnectionFactoryBean 创建的 RabbitMQ ConnectionFactory 实例也默认禁用了此选项。
通用更改
ExchangeBuilder 现在默认构建持久化的交换器。在 @QueueBinding 中使用的 @Exchange 注解也默认声明持久化的交换器。在 @RabbitListener 中使用的 @Queue 注解默认情况下,如果队列是命名的,则声明持久化的队列;如果是匿名的,则声明非持久化的队列。更多信息请参阅 队列和交换器的构建器 API 和 注解驱动的监听器端点。
已删除的类
UniquelyNameQueue 不再提供。创建一个具有唯一名称的持久化非自动删除队列是不常见的。该类已被删除。如果你需要其功能,请使用 new Queue(UUID.randomUUID().toString())。
新的监听器容器
Log4j 附加器
由于 log4j 的生命周期结束,此 appender 不再可用。有关可用的日志 appender 信息,请参阅 日志子系统 AMQP Appenders。
RabbitTemplate 变更
以前,如果一个非事务性的 RabbitTemplate 在事务性监听器容器线程上运行,它会参与现有的事务。这是一个严重的 bug。然而,用户可能已经依赖了这种行为。从 1.6.2 版本开始,你必须在模板上设置 channelTransacted 布尔值,以便它参与容器事务。
RabbitTemplate 现在(默认情况下)使用 DirectReplyToMessageListenerContainer,而不是为每个请求创建新的消费者。更多信息请参阅 RabbitMQ Direct reply-to。
AsyncRabbitTemplate 现在支持直接回复功能。有关更多信息,请参阅 Async Rabbit Template。
RabbitTemplate 和 AsyncRabbitTemplate 现在提供了 receiveAndConvert 和 convertSendAndReceiveAsType 方法,这些方法接受一个 ParameterizedTypeReference<T> 参数,允许调用者指定要将结果转换成的类型。这对于复杂类型或在消息头中未传递类型信息的情况特别有用。这需要一个 SmartMessageConverter,例如 Jackson2JsonMessageConverter。更多信息请参见请求/回复消息传递、异步 Rabbit 模板、使用 RabbitTemplate 从消息转换 和 使用 RabbitTemplate 从消息转换。
你现在可以使用 RabbitTemplate 在专用通道上执行多个操作。更多信息请参见范围操作。
监听器适配器
为了方便使用 lambda 表达式与 MessageListenerAdapter 结合,提供了一个 FunctionalInterface。更多信息请参阅 MessageListenerAdapter。
监听器容器变更
预取默认值
之前的预取默认值为 1,这可能导致高效消费者的利用率不足。现在的默认预取值为 250,在大多数常见场景下应该能让消费者保持忙碌,从而提高吞吐量。
在某些场景下,预取值(prefetch value)应该设置得较低——例如,处理大消息时,尤其是当处理速度较慢时(消息可能会在客户端进程中累积占用大量内存),以及当需要严格的消息顺序时(在这种情况下,预取值应设置为 1)。此外,在低流量消息传递和多消费者(包括单个监听器容器实例内的并发)的情况下,您可能希望减少预取值,以便在消费者之间更均匀地分配消息。
有关 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 解析器
在解析 Queue 和 Exchange XML 组件时,如果存在 id 属性,解析器将不再将 name 属性值注册为 bean 别名。更多信息请参阅 关于 id 和 name 属性的说明。
被阻塞的连接
你现在可以将 com.rabbitmq.client.BlockedListener 注入到 org.springframework.amqp.rabbit.connection.Connection 对象中。此外,当连接被 Broker 阻塞或解除阻塞时,ConnectionFactory 会发出 ConnectionBlockedEvent 和 ConnectionUnblockedEvent 事件。
有关更多信息,请参见连接与资源管理。