Java 如何处理 JMS 中的消息顺序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2252085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle order of messages in JMS?
提问by user271858
I am reviewing a client-server application written in Java. The server receives JMS messages and processes them but the messages can come in an unexpected order, and a cancel can arrive before an order message. How do you handle such a case? Do you do it in the mdb?
我正在用 Java 编写的客户端-服务器应用程序。服务器接收 JMS 消息并处理它们,但这些消息可能以意外的顺序出现,并且取消可能在订单消息之前到达。你怎么处理这样的情况?你是在mdb里做的吗?
What are some strategies or patterns for this kind of scenario?
这种场景有哪些策略或模式?
采纳答案by ewernli
So far I know, this is refereed to as "out-of-order" delivery and is part of the quality of service (QoS) attributes of the JMS system. I don't think it's part of the JMS specification, but some provider support it maybe. That will depend on the particular JMS implementation you use.
到目前为止,我知道,这被称为“无序”交付,并且是 JMS 系统的服务质量 (QoS) 属性的一部分。我不认为它是 JMS 规范的一部分,但某些提供者可能支持它。这将取决于您使用的特定 JMS 实现。
Note however that JMS is meant to distribute messages to severalconsumers in a way to distribute the load. If message have to be delivered in an ordered fashion this is not possible -- it basically lead to serialization of the message delivery and message could not be processed concurrently.
但是请注意,JMS 旨在以分配负载的方式将消息分配给多个使用者。如果消息必须以有序的方式传递,这是不可能的——它基本上会导致消息传递的序列化,并且无法同时处理消息。
The wikipediasays it better than me:
在维基百科说,它比我好:
JMS queueA staging area that contains messages that have been sent and are waiting to be read. Note that, contrary to what the name queue suggests, messages don't have to be delivered in the order sent. If the message driven bean pool contains more than one instance then messages can be processed concurrently and thus it is possible that a later message is processed sooner than an earlier one. A JMS queue guarantees only that each message is processed only once.
JMS 队列一个暂存区,其中包含已发送并等待读取的消息。请注意,与名称队列所建议的相反,消息不必按发送顺序传递。如果消息驱动的 bean 池包含多个实例,则可以并发处理消息,因此后一条消息可能比前一条消息处理得更快。JMS 队列仅保证每条消息只处理一次。
Out-of-band cancel request is not easy to achieve with JMS then. Two ideas:
那么带外取消请求就很难用 JMS 实现了。两个想法:
- Store a ticket which corresponds to each message in a database could be used to cancel message easily. When the message is delivered, the MDB check if the corresponding ticket is still valid. If yes, proceeds further, if not, drop the message.
- Try to set the MDB pool size to one. Maybe in this case, the delivery will be ordered. Changing the pool size is app. server specific, but most of them support per-bean pool size.
- 将与每条消息对应的票证存储在数据库中可用于轻松取消消息。当消息被传递时,MDB 检查相应的票证是否仍然有效。如果是,继续进行,如果不是,则丢弃该消息。
- 尝试将 MDB 池大小设置为 1。也许在这种情况下,将订购交货。更改池大小是应用程序。特定于服务器,但大多数都支持每个 bean 的池大小。
Otherwise, have maybe a look at the message storepattern. It's anyway worth checking the EAIwebsite.
回答by SteveD
Your system will be a lot more flexible if it can cope with the out-of-order messages. The pattern I've used to solve this in the past is to use a delay queue (on a system that processed 8 million messages-per-day in the financial world).
如果您的系统能够处理乱序消息,它将会更加灵活。我过去用来解决这个问题的模式是使用延迟队列(在金融界每天处理 800 万条消息的系统上)。
In your example, if I received a delete for an order I hadn't received yet, I'd delay it for a period of time and retry. If I still knew nothing about the order I'm being asked to delete, I'd raise some sort of error (reply to the original sender, send a message to a special error queue, ...).
在您的示例中,如果我收到了对尚未收到的订单的删除,我会将其延迟一段时间并重试。如果我仍然对我被要求删除的订单一无所知,我会引发某种错误(回复原始发件人,将消息发送到特殊的错误队列,......)。
As to the implementation of the delay queue, this can be another JMS queue with a service that can accept messages to be delayed. It then periodically reads the delayed messages and checks if the delayed time period has expired and re-submit the message to the original destination queue.
至于延迟队列的实现,可以是另一个JMS队列,有一个可以接受延迟消息的服务。然后它会定期读取延迟消息并检查延迟时间段是否已过期,然后将消息重新提交到原始目标队列。
回答by p.marino
I second the advice about checking the EAI site, and the book it is based on (a fantastic text on MOMs and MOM patterns).
我第二个关于检查 EAI 站点的建议,以及它所基于的书(关于 MOM 和 MOM 模式的精彩文本)。
Personally I'd investigate the Resequencer, though.
不过,我个人会调查Resequencer。
回答by simgineer
How to assure the sequence of message received by mdb?is about a similar topic on the server side where someone indicates that ActiveMQmight have a solution that preserves order. I guess this makes it verdor specific though.
如何保证mdb接收到的消息顺序?是关于服务器端的类似主题,有人指出ActiveMQ可能有一个保留顺序的解决方案。我想这使它变得特定。