Amazon SQS FIFO是否保证消息有序?Spring Boot集成时消费乱序问题排查
问题原因分析
- 消费端默认多线程并发消费
你使用的@SqsListener默认配置了大于1的并发消费线程数,同时默认单次拉取多条消息(默认MaxNumberOfMessages为10)。即便SQS FIFO队列会按顺序将同一消息组的消息投递给消费端,多线程并行处理不同消息时,执行速度的差异会导致先拿到的消息后处理完成打印,最终出现日志乱序。 - 发送端异步发送可能导致消息入队顺序错乱
默认QueueMessagingTemplate的convertAndSend是异步发送逻辑,for循环批量调用时,请求实际到达AWS SQS服务端的顺序可能和你调用顺序不一致,导致消息本身入队顺序就不对。
修复方案
1. 调整消费端配置为单线程串行消费
在你的application.properties(或application.yml)中添加如下配置,限制每次只拉取1条消息,且只用1个线程消费:
# 每次仅拉取1条消息 spring.cloud.aws.sqs.listener.max-number-of-messages=1 # 消费并发数设置为1 spring.cloud.aws.sqs.listener.concurrency=1
如果你是用代码配置SimpleMessageListenerContainer的话,也可以直接在配置类里设置对应的并发数和最大拉取消息数属性。
2. 确保发送端消息按顺序入队
如果调整消费端后还有乱序问题,就修改发送逻辑为同步发送,确认前一条消息发送成功后再发下一条,你可以给QueueMessagingTemplate设置同步发送配置,或者在发送后等待确认结果即可。
调整后重新启动服务,所有消息都会按你发送的顺序串行处理,控制台打印的日志就会按0到24的顺序输出。
内容的提问来源于stack exchange,提问作者Abhijith V Nair
相关产品推荐
相关产品推荐

