MQ JMS API中,发送方如何知道消息何时已被消费?

3
我正在处理一个独立的MQ JMS应用程序,我们的应用程序需要“知道”客户端已经消耗了生产者放在队列上的消息。因为客户端应用程序不是我们负责的。所以我们不能让他们在他们的一侧写入类似“msg.acknowledge();”的东西(在我的情况下,msg.acknowledge()不是正确的方法)。我在stackoverflow中搜索历史答案。发现以下内容与我想要的相当接近:https://stackoverflow.com/questions/6521117/how-to-guarantee-delivery-of-the-message-in-jmsDo the JMS spec or the various implementations support delivery confirmation of messages?
我的问题是,在MQ API或JMS API中是否有其他方法可以实现这一点?我只需要在消息生成方面进行编码,它可以是队列或主题。
另一个问题是,在JMS中,确认模式CLIENT_ACKNOWLEDGE是否无关紧要?我一直认为这种模式可以阻止应用程序调用send()方法,直到客户端消耗消息并调用msg.acknowledge(),但似乎并非如此。生产者仅在传递消息后退出应用程序,并且消息仅存储在队列中,直到客户端调用acknowledge()。是否可能让生成者应用程序挂起等待客户端确认消息?
如果我的概念不正确,请纠正我,谢谢。
1个回答

8
消息队列的主要目的是解耦生产者和消费者。生产者不需要等待消息被消费者消费,它可以继续执行其作业。如果生产者需要知道消息是否已被消费者处理,最理想的情况是它应该等待消费者在另一个队列上发送响应消息。
消息确认与生产者无关。消息确认是消费者告诉消息提供程序在将消息传递到应用程序后从队列中删除消息的方式。
有自动确认,JMS提供程序(如MQ JMS)将消息传递给应用程序后,告诉消息提供程序从队列中删除消息。然后有客户端确认,在接收到消息后,应用程序显式地告诉消息提供程序从队列中删除消息。
生产者必须等待消费者接收消息的原因是什么?一种方法,虽然不太优雅,但可以:发送消息后,使用已发送消息的消息ID并尝试浏览该消息。如果找不到消息,则可以假定它已被消费。

谢谢Shashi,你的回复非常有用。我们需要知道消费者已经收到了消息并记录了时间戳。因此,我们需要知道消费者是否已经收到了消息。使用主题来实现这个目的怎么样?这是不是有所不同?我知道主题可以同步传递消息。如果我使用持久订阅,能够满足我的要求吗? - phyerbarte
顺便问一下,正如你所提到的,我们可以从队列中检查消息ID,以确保消息是否已被客户端消费,这就是所谓的JMS浏览吗?我对JMS技术细节不是很熟悉,只是想确认一个方向,然后我可以深入了解。再次感谢。 - phyerbarte
@Shashi,在MQ(IBM)中,客户端是否必须发送确认消息已读取?如果不是,那么自动确认消息是在什么时候发送回Q管理器的?是在onMessage被调用后立即发送吗? - bluelurker
如果使用AUTO_ACKNOWLEDGE模式,应用程序不必发送任何确认。这是由JMS客户端完成的。我认为JMS客户端在onMessage方法返回后确认消息。 - Shashi
@Shashi 如果 onMessage 中出现异常并且线程死亡,那么消息是否仍然存在于队列中?我遇到了类似的问题,其中 onMessage 中有一个异常,并且由于未处理的异常而导致线程死亡。我可以清楚地在日志中看到消息已从队列中读取,但是如果线程死亡,则不会从队列中删除该消息。您知道这是否是预期行为吗? - bluelurker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接