Payara 5.2022.5中无法从DLQ获取已有JMS消息的问题排查
Payara 5.2022.5中无法从DLQ获取已有JMS消息的问题排查
嘿,我来帮你排查这个问题!你遇到的情况确实有点反常——明明用QueueBrowser能看到DLQ里的消息,但调用dlqConsumer.receive(5000)却返回null,导致while循环根本不执行。咱们一步步拆解可能的原因和解决办法:
最可能的原因:JMS连接未启动
这是JMS开发里非常容易踩的坑:JMS连接默认处于停止状态,如果不主动调用queueConn.start(),消费者根本不会开始接收消息!
你看你的代码,创建完queueConn之后直接去创建会话和消费者了,完全没启动连接。这就好比你插了网线但没点“连接网络”,自然收不到数据。
代码修改建议
在创建QueueSession之前,加上启动连接的代码:
queueConn = connectionFactory.createQueueConnection(); // 新增这一行,启动JMS连接 queueConn.start(); QueueSession queueSession = queueConn.createQueueSession(true, QueueSession.AUTO_ACKNOWLEDGE);
其他值得排查的点
如果加了start()还是不行,可以检查下面这些地方:
- 事务会话的确认模式冲突:你创建的是事务性会话(第一个参数为
true),此时第二个参数的AUTO_ACKNOWLEDGE会被JMS规范忽略——事务性会话的消息确认完全由commit()和rollback()控制。不过这个本身不会导致收不到消息,但要注意如果事务回滚,消息会回到DLQ。 - DLQ的权限配置:虽然
QueueBrowser能读取消息,但消费者可能缺少消费DLQ消息的权限。可以检查Payara控制台里DLQ的权限设置,或者在应用的部署描述文件(比如glassfish-ejb-jar.xml)中配置对应的JMS消费权限。 - 消息状态问题:确认DLQ里的消息不是处于“已被其他消费者锁定”的状态——如果有其他消费者已经获取了这些消息但没提交事务,你这边的消费者就看不到它们。可以用Payara的管理控制台查看DLQ的消息状态。
额外的代码优化提示
你的代码里每次处理一条消息就调用queueSession.commit(),这个逻辑是没问题的,但可以考虑把commit()放在循环外(如果toResubmit数量不大的话),不过当前的方式更安全,能避免一条消息失败导致全部回滚。
备注:内容来源于stack exchange,提问作者JustinKSU
相关产品推荐
相关产品推荐

