WebSphere JMS队列重复接收消息及消息内容格式化问题求助
针对WebSphere默认JMS提供者的两个问题解决方法
问题1:消息重复接收直到达到5次投递次数
核心原因
WebSphere SIBus默认会在消息未被正确确认/事务未提交时触发重投,5次是默认的最大失败投递次数。要实现一次接收就移除消息,关键是确保消息被成功确认或事务提交。
具体解决步骤
非事务场景:配置自动确认模式
创建QueueSession时,明确指定AUTO_ACKNOWLEDGE模式,WebSphere会在receive()方法成功返回后自动确认消息,直接从队列移除:// 非事务会话 + 自动确认 QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);注意:如果接收消息后抛出未捕获的异常,WebSphere会判定处理失败,依然会触发重投,所以要确保消息处理逻辑无未捕获异常。
事务场景:必须提交事务
如果用事务会话(SESSION_TRANSACTED),处理完消息后必须调用session.commit(),否则事务回滚,消息会被重新投递:// 事务会话 QueueSession session = connection.createQueueSession(true, Session.SESSION_TRANSACTED); QueueReceiver receiver = session.createReceiver(queue); Message msg = receiver.receive(); // 处理消息逻辑 session.commit(); // 提交事务后消息才会被移除验证队列配置(可选)
登录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
相关产品推荐
相关产品推荐

