我们开发了一个Java应用程序,其中多个Java JMS客户端使用Websphere MQ 7.0.1.9连接到服务器。每个客户端都有具有应用程序特定客户端ID的选择器,例如共享队列上的JMSCorrelationID ='050_14133431',其中服务器通过setJMSCorrelationID()发送给特定客户端的消息设置特定于应用程序的客户端ID。应用程序特定客户端ID是唯一的。它大部分时间都可以正常工作。但是,我们刚刚发现客户端B会丢失一些客户端A sessionId的消息。我检查了日志并确认每个客户端只在其sessionId上创建带有选择器的消费者。根据我的理解,消费者只消费符合选择标准的消息。需要注意的一点是,我使用预读功能,因为我们的应用程序使用非持久性消息。这种情况很少发生,比如一个月一次。知道为什么会这样吗? JMSCorrelationID ='050_14133431'中的任何语法错误,它是否必须以字母而不是数字开头?任何提示都表示赞赏。提前谢谢。
答案 0 :(得分:0)
请查看以下JMS文档(Emphasis mine):
JMS API支持的交付模式是PERSISTENT和 NON_PERSISTENT。
如果感觉到某个消息,客户端会将消息标记为持久消息 如果邮件在传输过程中丢失,应用程序将出现问题。一个 如果偶尔丢失消息,客户端会将消息标记为非持久性 是可以容忍的。客户端使用传递模式告诉JMS提供者如何操作 平衡消息传输可靠性与吞吐量。
传递模式仅涵盖将邮件传输到其传输 目的地。在目的地保留消息,直到消息为止 PERSISTENT交货不保证确认收据 模式。客户端应假定已设置邮件保留策略 行政。邮件保留策略管理的可靠性 从目的地到消息使用者的消息传递。例如,如果 客户端的消息存储空间已用完,某些消息可能已用完 根据特定于站点的邮件保留策略删除。
保证一条消息由JMS一次传递一次 提供者,如果消息的传递模式是PERSISTENT ,如果是 目的地有足够的邮件保留政策。
https://docs.oracle.com/javaee/6/api/javax/jms/DeliveryMode.html
在摘要中,如果邮件被标记为NON_PERSISTENT,则JMS提供程序无法保证一次且仅一次传递。如果不可接受,则应将其更改为PERSISTENT模式。
此外,您应该使用生产量的消息执行弹性(非功能)测试(使用Broker故障转移等方案),以找出重复消息的平均数量。