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

WebSphere JMS队列重复接收消息及消息内容格式化问题求助

针对WebSphere默认JMS提供者的两个问题解决方法

问题1:消息重复接收直到达到5次投递次数

核心原因

WebSphere SIBus默认会在消息未被正确确认/事务未提交时触发重投,5次是默认的最大失败投递次数。要实现一次接收就移除消息,关键是确保消息被成功确认或事务提交。

具体解决步骤

  1. 非事务场景:配置自动确认模式
    创建QueueSession时,明确指定AUTO_ACKNOWLEDGE模式,WebSphere会在receive()方法成功返回后自动确认消息,直接从队列移除:

    // 非事务会话 + 自动确认
    QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    

    注意:如果接收消息后抛出未捕获的异常,WebSphere会判定处理失败,依然会触发重投,所以要确保消息处理逻辑无未捕获异常。

  2. 事务场景:必须提交事务
    如果用事务会话(SESSION_TRANSACTED),处理完消息后必须调用session.commit(),否则事务回滚,消息会被重新投递:

    // 事务会话
    QueueSession session = connection.createQueueSession(true, Session.SESSION_TRANSACTED);
    QueueReceiver receiver = session.createReceiver(queue);
    Message msg = receiver.receive();
    // 处理消息逻辑
    session.commit(); // 提交事务后消息才会被移除
    
  3. 验证队列配置(可选)
    登录WebSphere管理控制台,进入Service integration -> Buses -> [你的总线名称] -> Destinations -> [目标队列],检查Maximum failed deliveries per message设置。不过只要确认/事务逻辑正确,这个参数不会影响正常处理的消息。


问题2:打印消息附带额外信息

原因

直接打印Message对象会调用其toString()方法,输出包含JMS头、属性等额外信息的字符串。要只打印消息内容,需要根据消息类型提取对应的消息体。

具体代码示例

根据你发送的消息类型(通常是TextMessage),提取纯内容:

Message receivedMsg = receiver.receive();
if (receivedMsg instanceof TextMessage) {
    // 文本消息直接获取内容
    TextMessage textMsg = (TextMessage) receivedMsg;
    System.out.println(textMsg.getText()); // 仅打印消息本身
} else if (receivedMsg instanceof BytesMessage) {
    // 字节消息转字符串
    BytesMessage bytesMsg = (BytesMessage) receivedMsg;
    byte[] contentBytes = new byte[(int) bytesMsg.getBodyLength()];
    bytesMsg.readBytes(contentBytes);
    System.out.println(new String(contentBytes));
}

避免直接打印receivedMsg对象,必须提取消息体内容后再打印。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:10:29