跳到主要内容
版本:4.1.1

消息监听器容器配置

Doubao 中英对照 Message Listener Container Configuration

配置 SimpleMessageListenerContainer(SMLC)和 DirectMessageListenerContainer(DMLC)时,与事务和服务质量相关的选项相当多,其中一些还会相互影响。适用于 SMLC、DMLC 或 StreamListenerContainer(StLC)(参见使用 RabbitMQ 流插件)的属性由相应列中的对勾标出。参见选择容器,了解帮助你决定哪种容器适合应用的信息。

下表展示了使用命名空间配置 <rabbit:listener-container/> 时的容器属性名及其等效属性名(括号中)。该元素的 type 属性可以是 simple(默认)或 direct,分别指定 SMLC 或 DMLC。有些属性不由命名空间暴露。这些在属性处以 N/A 标出。

表 1. 消息监听器容器的配置选项

属性(属性名)说明SMLCDMLCStLC

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 是事务性的,其事务与外部事务同步。✓✓