论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
DevOps与敏捷开发
›
【RabbitMQ的监听器容器Simple和Direct】 实现和场景区 ...
【RabbitMQ的监听器容器Simple和Direct】 实现和场景区别
耶耶耶耶耶
金牌会员
|
2025-2-12 16:01:16
|
显示全部楼层
|
阅读模式
楼主
主题
982
|
帖子
982
|
积分
2946
在Spring Boot中,RabbitMQ的两种监听器容器(SimpleMessageListenerContainer和DirectMessageListenerContainer)在实现机制和使用场景上有明显差异。以下是它们的核心区别、设置方式及最佳实践:
Simple类型
Direct类型
一、核心区别
特性
SimpleMessageListenerContainer
DirectMessageListenerContainer
线程模型
单线程管理全部消费者(线程池复用)每个消费者独立线程(更轻量级)
并发控制
动态调解消费者线程池concurrentConsumers固定每个队列的消费者数量(consumersPerQueue)
消息预取(Prefetch)
高预取大概导致消息堆积低预取(默认1)更公平的消息分配
资源斲丧
高(长连接、线程池)低(按需创建线程)
实用场景
长耗时任务、需动态扩缩容消费者、负载平衡场景高吞吐、低延迟、短任务 ;固定消费者数量、严格顺序处理场景
版本支持
旧版默认(Spring AMQP 1.x)新版默认(Spring Boot 2.0+)
二、Spring Boot设置示例
1. 全局设置(application.yml)
spring:
rabbitmq:
listener:
type: direct # 可选 simple 或 direct
simple:
concurrency: 5 # 初始消费者数
max-concurrency: 10 # 最大动态扩展数
prefetch: 50 # 每次预取消息数
type: direct
direct:
consumersPerQueue: 1 # 保持默认,确保顺序性
missingQueuesFatal: true # 生产环境建议开启,避免消息丢失
acknowledge-mode: manual # 推荐手动确认模式(更可控)
retry:
enabled: true
max-attempts: 3 # 总尝试次数 = 初始消费 + 2次重试
initial-interval: 2000ms # 首次重试间隔
multiplier: 2 # 指数退避策略
max-interval: 10000ms # 最大间隔保护
stateless: false # 必须设为 false(确保事务性操作)
重试过程示范
假设一个订单处理场景,消息内容为 {"orderId": 1001}:
首次消费尝试
消费者线程开始处理消息。
若业务逻辑抛出异常(如数据库连接失败),触发重试机制。
消息进入 retry 状态,等待 2秒。
第二次重试
间隔时间 = initial-interval * multiplier = 2s * 2 = 4s。
若仍失败,继续等待 4秒。
第三次重试
间隔时间 = 4s * 2 = 8s
(但不超过 max-interval 的 10s,即再有下一次,那么4s * 3 = 12s,超过了最大间隔10s,仍按最大间隔10s执行)。
最终失败后,根据配置执行以下操作之一:
手动确认模式:调用 basicNack(requeue=false),消息进入死信队列。
自动确认模式:抛出 AmqpRejectAndDontRequeueException 拒绝消息。
监控与告警建议
监控指标:
重试次数 (rabbitmq_listener_retry_count)
死信队列堆积量 (rabbitmq_queue_messages_dlx)
日志记录:
使用 MDC 记录消息 ID 和重试次数。
在最后一次重试失败时发送告警通知(如钉钉、Slack)。
复制代码
2. 注解式监听器
@RabbitListener(queues = "myQueue", containerFactory = "simpleContainerFactory")
public void handleMessage(String payload) {
// 业务逻辑
}
复制代码
3. 自界说容器工厂
@Configuration
public class RabbitConfig {
// Simple 容器工厂
@Bean(name = "simpleContainerFactory")
public SimpleRabbitListenerContainerFactory simpleFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setConcurrentConsumers(5);
factory.setMaxConcurrentConsumers(10);
factory.setPrefetchCount(50);
return factory;
}
// Direct 容器工厂
@Bean(name = "directContainerFactory")
public DirectRabbitListenerContainerFactory directFactory(ConnectionFactory connectionFactory) {
DirectRabbitListenerContainerFactory factory = new DirectRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setConsumersPerQueue(2);
factory.setPrefetchCount(1);
return factory;
}
}
复制代码
三、使用场景与最佳实践
1. 选择 Simple 容器的场景
长耗时任务
:如生成PDF报表、视频转码,需控制并发制止资源耗尽。
复杂错误处理
:需自界说重试策略(如RetryTemplate)和死信队列(DLQ)设置。
动态负载平衡
:通过调解concurrency和max-concurrency,自动扩展消费者线程应对流量高峰。
高吞吐场景
:结合prefetch批量拉取消息,淘汰网络开销(比方日志处理、批量任务)。
2. 选择 Direct 容器的场景
高吞吐低延迟
:如订单创建、秒杀体系,要求快速响应。
资源敏感型应用
:容器轻量,适合云环境或容器化摆设(如K8s)。
公平消息分发
:低预取(prefetch=1)确保消息均匀分配给消费者。
固定资源分配
:需严格控制每个队列的消费者数量(如支付回调等关键业务)。
顺序性要求
:单个队列绑定固定消费者,保证消息顺序处理(如库存扣减)。
精细化重试控制
:通过retry设置实现自界说重试逻辑(如短信发送失败重试)。
3. 最佳实践
根据业务选择类型
:
若需弹性伸缩,选择
Simple监听器
。
若需资源隔离或顺序保证,选择
Direct监听器
。
预取值(Prefetch)调优
:
高吞吐场景:增大prefetch淘汰网络交互(但大概增长内存压力)。
低延迟场景:减小prefetch以快速响应新消息。
消息确认与重试
:
使用manual确认模式,并在非常时调用channel.basicNack()触发重试或死信队列。
错误处理
:
始终设置Dead Letter Exchange(DLX)和重试机制。
监控与线程管理
:
监控消费者线程状态,制止Simple模式下线程数过高导致资源耗尽。
Direct模式下需评估队列数量与消费者配比,制止队列闲置。
通过RabbitMQ Management控制台监控队列堆积环境,调解prefetch和并发数。
版本适配
:
Spring Boot 2.x+默认使用Direct,如需切换回Simple需显式设置。
四、常见题目
Q1: 消息堆积时怎样选择容器?
若消息处理快,用Direct并增长consumers-per-queue。
若处理慢,用Simple并逐步提升max-concurrency,同时优化业务逻辑。
Q2: 怎样制止消息重复消费?
确保业务逻辑幂等(如数据库唯一约束)。
启用手动确认模式(acknowledge-mode: manual),在业务完成后手动ACK。
Q3: Direct容器为何偶然效率低?
检查prefetch是否过小(如默认1),得当增长以平衡吞吐和公平性。
listener的类型,其中simple和direct有不同的设置参数。比如,simple监听器可以设置并发消费者数量(concurrency和max-concurrency),而direct监听器则设置每个队列的消费者数量(consumers-per-queue)。这说明两者的并发处理方式不同,simple大概更适合动态调解消费者数量,而direct则固定每个队列的消费者数量。
单模式适合负载平衡,通过多个消费者处理同一队列的消息,而direct监听器大概更适合必要严格顺序或固定消费者的场景。
simple监听器提供更多的动态并发设置,适合必要横向扩展消费者的场景,而direct监听器则提供更固定的消费者数量设置,适合必要精确控制的场景。设置时必要注意各自的参数,如并发数、预取值、确认模式等。
通过公道选择容器类型和调优参数,可以明显提升RabbitMQ在Spring Boot中的性能和可靠性。发起结合压力测试和现实业务场景进行验证。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
耶耶耶耶耶
金牌会员
这个人很懒什么都没写!
楼主热帖
为什么你应该停止依赖Jenkins的插件? ...
蜻蜓优化算法(Matlab完整代码实现) ...
集合论第6-8章
axios&spring前后端分离传参规范总结 ...
SQL 教程之 10 个 SQL 操作用于 80% 的 ...
关于Maven的使用
Python知识点(史上最全)
腾讯云多媒体文件处理总结
JVM常用调优配置参数
20220319编译OpenHarmony-v3.1-beta出 ...
标签云
AI
运维
CIO
存储
服务器
快速回复
返回顶部
返回列表