You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用amazon-sqs-java-messaging-lib与@JmsListener启动时接收2条消息问题

解决amazon-sqs-java-messaging-lib启动自动接收2条消息的问题

我之前也碰到过类似的情况,结合对Spring JMS和Amazon SQS Java Messaging Lib的实际使用经验,给你几个排查和解决的方向:

首先,先排除最直观的可能性:

  • 检查SQS队列的遗留消息:登录AWS控制台找到你的目标队列,看看「Messages Available」的数量是不是刚好是2条。如果是的话,这些就是之前没被正确处理或清理的消息,服务启动时Listener容器会自动拉取这些待处理消息。你可以先手动删除这些测试/遗留消息,再重启服务验证问题是否消失。

如果队列本身是空的,那问题大概率出在Listener容器的配置上,你可以调整以下参数:

  • 限制并发消费者与消息获取量:默认的DefaultJmsListenerContainerFactory可能会有一些默认配置导致启动时拉取多条消息。你可以在配置Bean时明确设置并发数和单次获取的最大消息数:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(SQSConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    // 设置并发消费者为1,避免多实例同时拉取消息
    factory.setConcurrency("1");
    // 限制每次任务最多获取1条消息
    factory.setMaxMessagesPerTask(1);
    // 设置接收超时,避免启动时无限制等待拉取
    factory.setReceiveTimeout(1000L);
    return factory;
}
  • 确认消息处理的ACK模式:如果你的消息处理逻辑没有正确完成确认,可能会导致消息被重新放回队列,进而在启动时被再次拉取。你可以显式设置会话确认模式,并在Listener方法中手动确认:
// 在容器工厂中设置确认模式
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);

然后在你的Listener方法里手动确认消息:

@JmsListener(destination = "your-target-queue")
public void processMessage(Message message) throws JMSException {
    // 这里写你的消息处理逻辑
    // 处理完成后手动确认
    message.acknowledge();
}

另外还要注意:如果你的服务之前异常退出,SQS里的消息可能因为没有被确认而重新变为可用状态,这也会导致启动时被拉取。建议确保你的消息处理逻辑是幂等的,即使重复消费也不会出现业务问题。

内容的提问来源于stack exchange,提问作者Dmytro Kozhemiakin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:28:43