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

迁移至Spring Boot 3后Artemis生产者监听器的重复投递抑制与DLQ问题

Artemis主备集群跨客户端通信问题排查与解决

背景信息

  • 集群环境:Artemis 2.17.0主备集群
  • 通信模块:
    • 遗留消费端:基于ActiveMQ Classic的OpenWire JMS库,部署消息监听器
    • 生产端:Spring Boot 3应用,使用artemis-jakarta-client(从Spring Boot 2.7的artemis-jms-client迁移而来)
  • 异常症状:
    • 迁移到Spring Boot 3后,仅应用启动后的第一条消息能被正常消费
    • 后续所有消息直接进入死信队列(DLQ)
    • 遗留监听器日志持续出现suppressing duplicate delivery on connection警告

问题根源分析

这个警告的本质是Artemis的重复消息投递抑制机制被触发,核心原因是Jakarta JMS客户端与OpenWire客户端的消息处理逻辑不兼容,具体触发点:

  • Jakarta JMS规范下的消息ID格式和OpenWire客户端预期格式不一致,导致Artemis误判消息重复
  • 生产端与消费端的ACK模式不匹配,Artemis认为消息未被正确确认,重复投递后触发抑制规则,最终路由到DLQ
  • 主备集群环境下,Jakarta客户端的连接复用逻辑和OpenWire监听器的会话状态冲突,导致后续消息投递上下文异常

解决方案步骤

1. 调整Artemis服务端重复检测配置

在Artemis的broker.xml中,针对目标队列或全局关闭/放宽重复消息检测:

<configuration>
  <core>
    <!-- 全局关闭重复检测(若业务允许) -->
    <message-duplicate-detection>false</message-duplicate-detection>
    
    <!-- 或针对特定队列精细化配置 -->
    <address-settings>
      <address-setting match="your.target.queue">
        <message-duplicate-detection>false</message-duplicate-detection>
        <!-- 调整最大投递次数,避免消息快速进入DLQ -->
        <max-delivery-attempts>3</max-delivery-attempts>
      </address-setting>
    </address-settings>
  </core>
</configuration>

如果必须保留重复检测,可尝试调大duplicate-detection-window-size参数,延长检测窗口,减少误判概率。

2. 统一生产端与消费端的ACK模式

在Spring Boot 3生产端显式指定ACK模式为AUTO_ACKNOWLEDGE,和遗留OpenWire监听器保持一致:

Java配置方式

@Configuration
public class ArtemisProducerConfig {
    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
        // 显式设置ACK模式为自动确认
        jmsTemplate.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
        return jmsTemplate;
    }
}

配置文件方式

在application.properties中添加:

spring.artemis.jms.acknowledge-mode=auto

3. 检查遗留OpenWire客户端的会话配置

确保遗留消费端的会话ACK模式配置正确,避免手动ACK遗漏导致的异常:

// 示例:创建自动确认模式的会话
Connection connection = openWireConnectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

4. 升级Artemis版本(可选)

Artemis 2.17.0版本相对老旧,后续稳定版本(如2.20.x及以上)对Jakarta JMS与OpenWire的兼容性做了针对性优化,升级后可能直接解决该问题。

验证步骤

  1. 重启Artemis集群及两个应用
  2. 连续发送多条测试消息,检查是否全部被正常消费,无消息进入DLQ
  3. 查看遗留监听器日志,确认suppressing duplicate delivery on connection警告不再出现

内容的提问来源于stack exchange,提问作者daniele andreoli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:25:43