消息监听器容器配置
配置 SimpleMessageListenerContainer(SMLC)和 DirectMessageListenerContainer(DMLC)时,与事务和服务质量相关的选项相当多,其中一些还会相互影响。适用于 SMLC、DMLC 或 StreamListenerContainer(StLC)(参见使用 RabbitMQ 流插件)的属性由相应列中的对勾标出。参见选择容器,了解帮助你决定哪种容器适合应用的信息。
下表展示了使用命名空间配置 <rabbit:listener-container/> 时的容器属性名及其等效属性名(括号中)。该元素的 type 属性可以是 simple(默认)或 direct,分别指定 SMLC 或 DMLC。有些属性不由命名空间暴露。这些在属性处以 N/A 标出。
表 1. 消息监听器容器的配置选项
| 属性(属性名) | 说明 | SMLC | DMLC | StLC |
|---|---|---|---|---|
ackTimeout (N/A) | 当设置了 messagesPerAck 时,此超时用作发送 ack 的替代手段。当新消息到达时,未 ack 消息数与 messagesPerAck 比较,距上次 ack 的时间与此值比较。任一条件为 true 时,消息即被确认。当没有新消息到达且存在未 ack 消息时,此超时是近似的,因为该条件只在每个 monitorInterval 检查一次。另见本表中的 messagesPerAck 和 monitorInterval。 | ✓ | ||
acknowledgeMode (acknowledge) | - NONE:不发送 ack(与 channelTransacted=true 不兼容)。RabbitMQ 称之为“autoack”,因为 broker 假定所有消息都已被 ack,消费者无需任何操作。- MANUAL:监听器必须通过调用 Channel.basicAck() 确认所有消息。- AUTO:容器自动确认消息,除非 MessageListener 抛出异常。注意 acknowledgeMode 与 channelTransacted — 如果 channel 是事务性的,除 ack 外 broker 还需要提交通知。这是默认模式。另见 batchSize。 | ✓ | ✓ | |
adviceChain (advice-chain) | 应用于监听器执行的 AOP 通知数组。可用于应用额外的横切关注点,例如 broker 宕机时的自动重试。注意,AMQP 错误后的简单重连由 CachingConnectionFactory 处理,只要 broker 仍然存活。 | ✓ | ✓ | |
afterReceivePostProcessors (N/A) | 在调用监听器之前调用的 MessagePostProcessor 实例数组。后处理器可以实现 PriorityOrdered 或 Ordered。该数组会排序,未排序的成员最后调用。如果后处理器返回 null,消息被丢弃(并在适当时确认)。 | ✓ | ✓ | |
alwaysRequeueWithTxManagerRollback (N/A) | 设置为 true 时,在配置了事务管理器的情况下回滚时始终重新入队消息。 | ✓ | ✓ | |
autoDeclare (auto-declare) | 设置为 true(默认)时,如果容器在启动期间检测到其至少一个队列丢失(也许因为它是 auto-delete 或过期队列),会使用 RabbitAdmin 重新声明所有 AMQP 对象(队列、交换机、绑定);但无论队列因何种原因丢失都会执行重新声明。要禁用此行为,把该属性设置为 false。注意,如果所有队列都丢失,容器会启动失败。:::note 在 1.6 版本之前,如果上下文中有多个 admin,容器会随机选择一个。如果没有 admin,它会在内部创建一个。在两种情况下,这都可能导致意外结果。从 1.6 版本开始,要让 autoDeclare 生效,上下文中必须恰好有一个 RabbitAdmin,或者必须使用 rabbitAdmin 属性在容器上配置对特定实例的引用。::: | ✓ | ✓ | |
在 1.6 版本之前,如果上下文中有多个 admin,容器会随机选择一个。如果没有 admin,它会在内部创建一个。在两种情况下,这都可能导致意外结果。从 1.6 版本开始,要让 autoDeclare 生效,上下文中必须恰好有一个 RabbitAdmin,或者必须使用 rabbitAdmin 属性在容器上配置对特定实例的引用。 | ||||
autoStartup (auto-startup) | 指示容器应在 ApplicationContext 启动时启动的标志(作为 SmartLifecycle 回调的一部分,在所有 bean 初始化之后发生)。默认为 true,但如果 broker 在启动时可能不可用,可以设置为 false,稍后在你知道 broker 就绪时手动调用 start()。 | ✓ | ✓ | ✓ |
batchSize (transaction-size) (batch-size) | 与设置为 AUTO 的 acknowledgeMode 一起使用时,容器尝试在发送 ack 之前最多处理此数量的消息(每条等待时间最长为接收超时设置)。这也是事务性 channel 提交的时机。如果 prefetchCount 小于 batchSize,会增大以匹配 batchSize。 | ✓ | ||
batchingStrategy (N/A) | 拆批消息时使用的策略。默认 SimpleDebatchingStrategy。参见批处理和带批处理的 @RabbitListener。 | ✓ | ✓ | |
channelTransacted (channel-transacted) | 布尔标志,表示所有消息都应在事务中确认(手动或自动)。 | ✓ | ✓ | |
concurrency (N/A) | m-n 每个监听器的并发消费者范围(最小值、最大值)。如果只提供 n,n 是固定消费者数。参见监听器并发。 | ✓ | ||
concurrentConsumers (concurrency) | 为每个监听器初始启动的并发消费者数。参见监听器并发。对于 StLC,并发通过重载的 superStream 方法控制;参见用单活动消费者消费超级流。 | ✓ | ✓ | |
connectionFactory (connection-factory) | 对 ConnectionFactory 的引用。使用 XML 命名空间配置时,默认引用的 bean 名称是 rabbitConnectionFactory。 | ✓ | ✓ | |
consecutiveActiveTrigger (min-consecutive-active) | 在考虑启动新消费者之前,一个消费者连续收到消息而未发生接收超时的最小数量。也受 'batchSize' 影响。参见监听器并发。默认值:10。 | ✓ | ||
consecutiveIdleTrigger (min-consecutive-idle) | 在考虑停止一个消费者之前,一个消费者必须经历的接收超时最小次数。也受 'batchSize' 影响。参见监听器并发。默认值:10。 | ✓ | ||
consumerBatchEnabled (batch-enabled) | 如果 MessageListener 支持,设置为 true 会启用离散消息的批处理,最多 batchSize;如果在 receiveTimeout 内没有新消息到达,或收集批消息时间超过 batchReceiveTimeout,将交付部分批次。为 false 时,批处理仅支持生产者创建的批次;参见批处理。 | ✓ | ||
consumerCustomizer (N/A) | 用于修改容器创建的流消费者的 ConsumerCustomizer bean。 | ✓ | ||
consumerStartTimeout (N/A) | 等待消费者线程启动的毫秒数。如果超过此时间,会写入错误日志。一个例子是配置的 taskExecutor 线程不足以支持容器的 concurrentConsumers。参见线程与异步消费者。默认值:60000(一分钟)。 | ✓ | ||
consumerTagStrategy (consumer-tag-strategy) | 设置ConsumerTagStrategy 的实现,从而为每个消费者创建(唯一)标签。 | ✓ | ✓ | |
consumersPerQueue (consumers-per-queue) | 为每个配置队列创建的消费者数。参见监听器并发。 | ✓ | ||
consumeDelay (N/A) | 当使用RabbitMQ 分片插件且 concurrentConsumers > 1 时,存在竞态条件,可能阻止消费者在分片间均匀分布。使用此属性在消费者启动之间添加小延迟以避免此竞态条件。你应通过试验数值来确定适合你环境的延迟。 | ✓ | ✓ | |
debatchingEnabled (N/A) | 为 true 时,监听器容器会拆批批处理消息,并对批次中的每条消息调用监听器。从 2.2.7 版本开始,如果监听器是 BatchMessageListener 或 ChannelAwareBatchMessageListener,生产者创建的批次会作为 List<Message> 拆批。否则批次中的消息会逐条呈现。默认 true。参见批处理和带批处理的 @RabbitListener。 | ✓ | ✓ | |
declarationRetries (declaration-retries) | 被动队列声明失败时的重试次数。被动队列声明发生在消费者启动时,或从多个队列消费时初始化期间并非所有队列都可用时。当重试耗尽后配置的队列仍无法被动声明(任何原因),容器行为由前面描述的 missingQueuesFatal 属性控制。默认值:三次重试(共四次尝试)。 | ✓ | ||
defaultRequeueRejected (requeue-rejected) | 确定因监听器抛出异常而被拒绝的消息是否应重新入队。默认值:true。 | ✓ | ✓ | |
errorHandler (error-handler) | 对 ErrorHandler 策略的引用,用于处理消息监听器执行期间可能发生的任何未捕获异常。默认值:ConditionalRejectingErrorHandler | ✓ | ✓ | |
exclusive (exclusive) | 确定此容器中的单个消费者是否对队列拥有独占访问。此为 true 时容器并发必须为 1。如果另一个消费者拥有独占访问,容器会根据 recovery-interval 或 recovery-back-off 尝试恢复消费者。使用命名空间时,此属性与队列名一起出现在 <rabbit:listener/> 元素上。默认值:false。 | ✓ | ✓ | |
exclusiveConsumerExceptionLogger (N/A) | 独占消费者无法访问队列时使用的异常记录器。默认在 WARN 级别记录。 | ✓ | ✓ | |
failedDeclarationRetryInterval (failed-declaration -retry-interval) | 被动队列声明重试尝试之间的间隔。被动队列声明发生在消费者启动时,或从多个队列消费时初始化期间并非所有队列都可用时。默认值:5000(五秒)。 | ✓ | ✓ | |
forceCloseChannel (N/A) | 如果消费者在 shutdownTimeout 内不响应关闭,此为 true 时 channel 会被关闭,导致任何未 ack 消息重新入队。2.0 起默认为 true。可以设置为 false 恢复以前行为。 | ✓ | ✓ | |
forceStop (N/A) | 设置为 true 时,在当前记录处理完后停止(容器停止时);导致所有预取消息重新入队。默认情况下,容器会取消消费者并在停止前处理所有预取消息。自 2.4.14、3.0.6 版本起。默认为 false。 | ✓ | ✓ | |
globalQos (global-qos) | 为 true 时,prefetchCount 全局应用于 channel,而不是 channel 上的每个消费者。更多信息参见 basicQos.global。 | ✓ | ✓ | |
| (group) | 仅使用命名空间时可用。指定时,会以此名称注册一个 Collection<MessageListenerContainer> 类型的 bean,每个 <listener/> 元素的容器都被添加到该集合。例如,这允许通过遍历集合来启动和停止这组容器。如果多个 <listener-container/> 元素具有相同的 group 值,集合中的容器形成所有如此指定容器的聚合。 | ✓ | ✓ | |
idleEventInterval (idle-event-interval) | 参见检测空闲异步消费者。 | ✓ | ✓ | |
javaLangErrorHandler (N/A) | 容器线程捕获 Error 时调用的 AbstractMessageListenerContainer.JavaLangErrorHandler 实现。默认实现调用 System.exit(99);要恢复以前行为(什么都不做),添加一个无操作处理器。 | ✓ | ✓ | |
maxConcurrentConsumers (max-concurrency) | 需要时按需启动的最大并发消费者数。必须大于或等于 'concurrentConsumers'。参见监听器并发。 | ✓ | ||
messagesPerAck (N/A) | 两次 ack 之间接收的消息数。用于减少发送给 broker 的 ack 数量(代价是增加消息重复投递的可能性)。通常,只应对高吞吐量监听器容器设置此属性。如果设置了此属性且某条消息被拒绝(抛出异常),待处理的 ack 会被确认,失败消息被拒绝。事务性 channel 不允许。如果 prefetchCount 小于 messagesPerAck,会增大以匹配 messagesPerAck。默认值:每条消息都 ack。另见本表中的 ackTimeout。 | ✓ | ||
mismatchedQueuesFatal (mismatched-queues-fatal) | 容器启动时,如果此属性为 true(默认:false),容器会检查上下文中声明的所有队列是否与 broker 上已有的队列兼容。如果存在不匹配的属性(如 auto-delete)或参数(如 x-message-ttl),容器(和应用上下文)会因致命异常启动失败。如果问题在恢复期间检测到(例如连接丢失后),容器会停止。 应用上下文中必须有唯一的 RabbitAdmin(或通过 rabbitAdmin 属性在容器上专门配置一个)。否则此属性必须为 false。:::note 如果初始启动时 broker 不可用,容器会启动,并在连接建立时检查这些条件。 ::: :::important 检查是针对上下文中的所有队列进行的,而不仅仅是某个监听器配置使用的队列。如果你希望把检查限制为仅某个容器使用的队列,应为该容器配置单独的 RabbitAdmin,并使用 rabbitAdmin 属性提供对它的引用。更多信息参见条件声明。::: :::important 在为标记为 @Lazy 的 bean 中的 @RabbitListener 启动容器期间,会禁用不匹配队列参数检测。这是为了避免潜在死锁,这种死锁可能延迟此类容器启动长达 60 秒。使用惰性监听器 bean 的应用应在获取惰性 bean 引用之前检查队列参数。::: | ✓ | ✓ | |
| 如果初始启动时 broker 不可用,容器会启动,并在连接建立时检查这些条件。 | ||||
检查是针对上下文中的所有队列进行的,而不仅仅是某个监听器配置使用的队列。如果你希望把检查限制为仅某个容器使用的队列,应为该容器配置单独的 RabbitAdmin,并使用 rabbitAdmin 属性提供对它的引用。更多信息参见条件声明。 | ||||
在为标记为 @Lazy 的 bean 中的 @RabbitListener 启动容器期间,会禁用不匹配队列参数检测。这是为了避免潜在死锁,这种死锁可能延迟此类容器启动长达 60 秒。使用惰性监听器 bean 的应用应在获取惰性 bean 引用之前检查队列参数。 | ||||
missingQueuesFatal (missing-queues-fatal) | 设置为 true(默认)时,如果配置的队列在 broker 上都不可用,则视为致命。这会导致应用上下文在启动期间初始化失败。此外,容器运行期间队列被删除时,默认情况下消费者会重试三次连接队列(间隔五秒),如果这些尝试失败则停止容器。这在以前版本中不可配置。 设置为 false 时,三次重试后,容器进入恢复模式,就像其他问题(如 broker 宕机)一样。容器根据 recoveryInterval 属性尝试恢复。每次恢复尝试期间,每个消费者再次以五秒间隔尝试四次被动声明队列。此过程无限持续。你也可以使用属性 bean 为所有容器全局设置此属性,如下所示(代码示例见英文对照)。 此全局属性不应用于任何显式设置了 missingQueuesFatal 属性的容器。默认重试属性(五秒间隔三次重试)可通过设置以下属性覆盖。 :::important 在为标记为 @Lazy 的 bean 中的 @RabbitListener 启动容器期间,会禁用缺失队列检测。这是为了避免潜在死锁,这种死锁可能延迟此类容器启动长达 60 秒。使用惰性监听器 bean 的应用应在获取惰性 bean 引用之前检查队列。::: | ✓ | ✓ | |
在为标记为 @Lazy 的 bean 中的 @RabbitListener 启动容器期间,会禁用缺失队列检测。这是为了避免潜在死锁,这种死锁可能延迟此类容器启动长达 60 秒。使用惰性监听器 bean 的应用应在获取惰性 bean 引用之前检查队列。 | ||||
monitorInterval (monitor-interval) | 对于 DMLC,会调度一个任务按此间隔运行,监控消费者状态并恢复任何失败的消费者。 | ✓ | ||
noLocal (N/A) | 设置为 true 可禁用服务器向消费者投递在同一 channel 连接上发布的消息。 | ✓ | ✓ | |
phase (phase) | 当 autoStartup 为 true 时,容器应在其中启动和停止的生命周期阶段。值越小,容器启动越早、停止越晚。默认值为 Integer.MAX_VALUE,意味着容器尽可能晚启动、尽可能早停止。 | ✓ | ✓ | |
possibleAuthenticationFailureFatal (possible-authentication-failure-fatal) | 设置为 true(SMLC 默认)时,如果连接期间抛出 PossibleAuthenticationFailureException,视为致命。这会导致应用上下文在启动期间初始化失败(如果容器配置为自动启动)。自_2.0 版本_起。 DirectMessageListenerContainer 设置为 false(默认)时,每个消费者会根据 monitorInterval 尝试重连。SimpleMessageListenerContainer 设置为 false 时,三次重试后容器进入恢复模式,就像其他问题(如 broker 宕机)一样。容器根据 recoveryInterval 属性尝试恢复。每次恢复尝试期间,每个消费者再次尝试启动 4 次。此过程无限持续。你也可以使用属性 bean 为所有容器全局设置此属性,如下所示(代码示例见英文对照)。 此全局属性不应用于任何显式设置了 missingQueuesFatal 属性的容器。默认重试属性(五秒间隔三次重试)可通过其后的属性覆盖。 | ✓ | ✓ | |
prefetchCount (prefetch) | 每个消费者上可未确认消息的最大数量。此值越高,消息投递越快,但非顺序处理的风险越高。acknowledgeMode 为 NONE 时忽略此值。必要时会增大此值以匹配 batchSize 或 messagePerAck。2.0 起默认为 250。可以设置为 1 恢复以前行为。:::important 有些场景下 prefetch 值应较低——例如大消息,尤其是处理缓慢时(消息可能在客户端进程中累积为大量内存),以及需要严格消息顺序时(此时 prefetch 值应设回 1)。此外,对于低吞吐量消息和多个消费者(包括单个监听器容器实例内的并发),你可能希望减小 prefetch 以获得消费者间更均匀的消息分布。 ::: 另见 globalQos。 | ✓ | ✓ | |
| 有些场景下 prefetch 值应较低——例如大消息,尤其是处理缓慢时(消息可能在客户端进程中累积为大量内存),以及需要严格消息顺序时(此时 prefetch 值应设回 1)。此外,对于低吞吐量消息和多个消费者(包括单个监听器容器实例内的并发),你可能希望减小 prefetch 以获得消费者间更均匀的消息分布。 | ||||
rabbitAdmin (admin) | 当一个监听器容器监听至少一个 auto-delete 队列,并在启动时发现该队列丢失,容器会使用 RabbitAdmin 声明该队列及任何相关绑定和交换机。如果这些元素配置为使用条件声明(参见条件声明),容器必须使用配置为声明这些元素的 admin。在此处指定该 admin。仅在使用带条件声明的 auto-delete 队列时需要。如果不希望 auto-delete 队列在容器启动前声明,请在 admin 上把 auto-startup 设置为 false。默认为声明所有非条件元素的 RabbitAdmin。 | ✓ | ✓ | |
receiveTimeout (receive-timeout) | 等待每条消息的最长时间。如果 acknowledgeMode=NONE,这几乎没有影响——容器转一圈再请求下一条消息。对于 batchSize > 1 的事务性 Channel 影响最大,因为它可能导致已消费消息在超时到期前不被确认。consumerBatchEnabled 为 true 时,如果此超时在批次完成前发生,将交付部分批次。 | ✓ | ||
batchReceiveTimeout (batch-receive-timeout) | 收集批消息的超时时长(毫秒)。它限制等待填满 batchSize 的时间。当 batchSize > 1 且收集批消息时间大于 batchReceiveTime 时,将交付批次。默认值为 0(无超时)。 | ✓ | ||
recoveryBackOff (recovery-back-off) | 指定消费者因非致命原因启动失败时,两次启动尝试之间间隔的 BackOff。默认是每五秒无限重试的 FixedBackOff。与 recoveryInterval 互斥。 | ✓ | ✓ | |
recoveryInterval (recovery-interval) | 确定消费者因非致命原因启动失败时,两次启动尝试之间的毫秒数。默认值:5000。与 recoveryBackOff 互斥。 | ✓ | ✓ | |
retryDeclarationInterval (missing-queue- retry-interval) | 如果消费者初始化期间配置的队列子集可用,消费者开始从这些队列消费。消费者尝试按此间隔被动声明丢失的队列。此间隔到期后,再次使用 'declarationRetries' 和 'failedDeclarationRetryInterval'。如果仍有丢失队列,消费者再次等待此间隔后重试。此过程无限持续,直到所有队列可用。默认值:60000(一分钟)。 | ✓ | ||
shutdownTimeout (N/A) | 容器关闭时(例如其所在 ApplicationContext 关闭时),等待在途消息处理的最长时限。默认为五秒。 | ✓ | ✓ | |
startConsumerMinInterval (min-start-interval) | 按需启动每个新消费者之前必须经过的毫秒数。参见监听器并发。默认值:10000(10 秒)。 | ✓ | ||
statefulRetryFatal (WithNullMessageId (N/A) | 使用有状态重试通知时,如果收到的消息缺少 messageId 属性,默认视为对消费者致命(消费者停止)。设置为 false 可丢弃(或路由到死信队列)此类消息。 | ✓ | ✓ | |
stopConsumerMinInterval (min-stop-interval) | 检测到空闲消费者时,自上次停止消费者后必须经过的毫秒数,然后才停止一个消费者。参见监听器并发。默认值:60000(一分钟)。 | ✓ | ||
streamConverter (N/A) | 把原生流消息转换为 Spring AMQP 消息的 StreamMessageConverter。 | ✓ | ||
taskExecutor (task-executor) | 对 Spring TaskExecutor(或标准 JDK 1.5+ Executor)的引用,用于执行监听器调用器。默认是使用内部管理线程的 SimpleAsyncTaskExecutor。 | ✓ | ✓ | |
taskScheduler (task-scheduler) | 对于 DMLC,用于按 'monitorInterval' 运行监控任务的调度器。 | ✓ | ||
transactionManager (transaction-manager) | 监听器操作的外部事务管理器。也与 channelTransacted 互补——如果 Channel 是事务性的,其事务与外部事务同步。 | ✓ | ✓ |