如何处理JMS中的消息顺序?

2022-09-01 15:51:33

我正在审查一个用Java编写的客户端 - 服务器应用程序。服务器接收 JMS 消息并对其进行处理,但这些消息可能以意外的顺序出现,取消消息可能先于订单消息到达。你是如何处理这样的案件的?你在mdb中这样做吗?

对于这种情况,有哪些策略或模式?


答案 1

到目前为止,我知道,这被称为“无序”交付,并且是JMS系统服务质量(QoS)属性的一部分。我不认为它是JMS规范的一部分,但一些提供商可能支持它。这将取决于您使用的特定 JMS 实现。

但请注意,JMS 旨在以一种分配负载的方式将消息分发给多个使用者。如果消息必须以有序方式传递,这是不可能的 - 它基本上会导致消息传递的序列化,并且无法同时处理消息。

维基百科比我说得更好:

JMS 队列一个暂存区域,其中包含已发送且正在等待读取的消息。请注意,与名称队列所建议的相反,消息不必按发送顺序传递。如果消息驱动的 Bean 池包含多个实例,则可以同时处理消息,因此处理较晚的消息可能比处理较早的消息早。JMS 队列仅保证每条消息只处理一次。

带外取消请求在 JMS 中并不容易实现。两个想法:

  • 在数据库中存储与每条消息相对应的票证可用于轻松取消消息。传递消息后,MDB 会检查相应的票证是否仍然有效。如果是,则继续,如果没有,则删除该消息。
  • 尝试将 MDB 池大小设置为 1。也许在这种情况下,将订购交货。更改池大小特定于应用程序服务器,但其中大多数都支持每个 Bean 池大小。

否则,可以查看消息存储库模式。无论如何,值得一看EAI网站。


答案 2

如果系统能够处理无序消息,它将更加灵活。我过去用来解决这个问题的模式是使用延迟队列(在金融世界中每天处理800万条消息的系统上)。

在您的示例中,如果我收到尚未收到的订单的删除,我会将其延迟一段时间并重试。如果我仍然对要求删除的订单一无所知,我会引发某种错误(回复原始发件人,向特殊错误队列发送消息等)。

至于延迟队列的实现,这可以是另一个JMS队列,其服务可以接受要延迟的消息。然后,它会定期读取延迟的消息,并检查延迟的时间段是否已过期,并将消息重新提交到原始目标队列。


推荐