Spring Boot+STOMP+RabbitMQ压测消息丢失问题求助
排查思路
1. 连接层参数校验
- 检查Spring Boot内嵌Tomcat的TCP连接配置:
server.tomcat.max-threads、server.tomcat.accept-count、server.tomcat.max-connections这几个参数是否能支撑80线程的瞬间并发。默认配置可能在短时间高并发下出现连接池打满,导致新连接被拒绝或重置。 - 核对服务器系统级TCP参数:
net.core.somaxconn(监听队列上限)、net.ipv4.tcp_syncookies(SYN洪水防护开关)、net.ipv4.tcp_fin_timeout,这些参数不合理会直接引发TCP连接重置。 - 检查JMeter连接配置:是否开启
keep-alive,连接超时时间是否过短。如果JMeter侧超时小于服务端处理时长,会主动断开连接导致消息发送中断。
2. STOMP与RabbitMQ交互问题排查
- 确认RabbitMQ STOMP插件状态:查看RabbitMQ日志是否有插件启动失败、报错信息,比如
Too many open files这类资源不足的提示,会导致无法创建新STOMP连接。 - 检查STOMP心跳配置:Spring Boot中
spring.rabbitmq.stomp.heartbeat参数如果设置不合理,会引发RabbitMQ主动断开连接,进而导致消息丢失。 - 验证消息发送确认机制:STOMP客户端发送消息时是否启用
receipt确认?未开启的话,高并发下无法确认消息是否成功送达RabbitMQ,容易出现客户端到MQ之间的消息丢失。 - 核对MQ队列/交换机配置:聊天消息绑定的交换机、队列是否正确?队列是否开启持久化?若使用临时队列,连接断开时队列会被删除,导致消息无法留存。同时检查RabbitMQ的
memory_high_watermark和disk_free_limit,达到阈值时MQ会停止接收消息,造成消息路由失败。
3. Spring Boot应用内部问题定位
- 检查应用线程池配置:处理STOMP消息的
TaskExecutor(对应spring.task.execution.*、spring.mvc.async.request-timeout参数)是否存在线程池满的情况,线程阻塞会导致消息处理延迟甚至连接超时重置。 - 排查应用日志异常:查看是否有消息转换错误、业务逻辑未捕获异常,这类问题会导致消息无法正确转发到聊天室,表现为“消息未送达”。
- 确认STOMP订阅时机:压测时是否存在客户端未完成订阅就发送消息的情况?比如JMeter脚本中没有等待订阅确认就发消息,会导致消息无法被接收方捕获。
- 监控应用资源占用:压测期间是否出现CPU打满、内存溢出?资源耗尽会导致应用无法及时处理连接和消息请求。
4. 压测脚本合理性验证
- 检查JMeter连接与订阅逻辑:是否确保每个线程的STOMP连接完全建立、订阅成功后再发送消息?比如添加
receipt确认订阅成功的步骤,或增加合理的等待时间,避免因订阅延迟导致消息丢失。 - 调整并发启动速率:将80线程1秒启动改为5秒或更长时间逐步启动,观察问题是否消失,以此判断是否是瞬间并发过高引发的资源过载。
- 确认连接独立性:JMeter是否为每个线程分配独立的STOMP连接?多线程共享连接会导致消息发送混乱或被服务器重置。
5. RabbitMQ日志重点分析
- 查找
connection_closed、connection_reset相关条目,明确是客户端主动断开还是RabbitMQ主动断开,以及具体断开原因(超时、认证失败、资源不足等)。 - 检查
channel_closed、queue_declare_failed日志,这些是消息路由失败、队列创建异常的直接线索。 - 监控压测期间的MQ指标:连接数、消息吞吐量、队列长度的变化曲线,是否存在异常峰值或持续积压。
内容的提问来源于stack exchange,提问作者dionisos198
相关产品推荐
相关产品推荐

