从 ActiveMQ 消费消息时如何保持消息顺序?

发布于 2024-07-11 16:06:10 字数 207 浏览 8 评论 0原文

我有一个使用 ActiveMQ 客户端的 .NET 服务。 我已经实现了一个带有事务处理连接的 MessageListener 来使用消息。

有时,我收到的消息的顺序与放入队列的顺序不同。

使用 MessageListner 是错误的吗? 有没有办法保留消息顺序?

仅供参考:有一个生产者将消息放入队列,一个消费者从队列中拉出消息。

I have a .NET service that uses the ActiveMQ client. I have implemented a MessageListener with a transacted connection to consume the messages.

Occasionally, I get messages in a different order in which they were put onto the queue.

Was it wrong to use a MessageListner? Is there a way to preserve the message order?

FYI: There is one producer putting messages on the queue and one consumer pulling messages off the queue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橘亓 2024-07-18 16:06:10

你不应该做任何事情来维持秩序; 这是消息队列为您做的事情之一。 我认为,如果您有一个消费者正在侦听队列,并且它正在无序处理消息,那么您要么发现了错误,要么消息没有按照您认为的顺序排队。

另外,还有来自 这个问题 href="http://activemq.apache.org/faq.html" rel="nofollow noreferrer">ActiveMQ 常见问题解答可能会有所帮助。

编辑:来自阅读duffymo 的回答,看起来你有点过度设计了。 一般来说,像ActiveMQ、MQ Series、joram等消息队列有两个特点:它们按照入队的顺序传递消息,并且保证消息传递。 发送单独的ACK消息是多余的; 这有点像提交数据库事务,然后查询相同的信息以仔细检查数据库是否实际存储了它。

话虽如此,你的服务器是多线程的吗? 如果是这样,它可能会在将 ACK 排入队列之前将响应排入队列。

You shouldn't have to do anything to maintain the order; that's one of the things that a message queue does for you. I would think that if you have a single consumer listening to the queue, and it is processing messages out of order, then you have either found a bug or the messages aren't enqueued in the order you think they are.

Also, there's this question from the ActiveMQ FAQ that might help.

Edit: From reading the comments on duffymo's answer, it looks like you're overengineering a bit. In general, a message queue like ActiveMQ, MQ Series, joram, etc. have two characteristics: they deliver messages in the same order in which they are enqueued, and they guarantee message delivery. Sending a separate ACK message is redundant; it's a bit like committing a database transaction, then querying the same information back to double-check that the database actually stored it.

Having said that, is your server multithreaded? If so it may possible for it to enqueue the response before it enqueues the ACK.

绝情姑娘 2024-07-18 16:06:10

更多信息:我调用的服务器是第三方的,我无法控制它发送的消息。 我确实知道,根据消息 ID,它们按正确的顺序放置。 此外,在该系统中,ACK 和 Acknowledge 之间存在差异。 当我的原始消息被放入“出站”队列时,就会收到 ACK。 然后,我监视“入站”队列中的响应。 我通常会得到“确认”,然后是“通过”或“失败”。 这些消息的相关 ID 是来自 ACK 的消息 ID。

我最初使用消息侦听器并响应 OnMessge 事件。 在意识到使用这种方法消息是异步传递的,因此没有特定的顺序后,我放弃了这种方法。 因此,我将代码更改为使用计时器 (System.Threading.Timer) 进行轮询,以调用 Consumer.Receive() 并一次获取一条消息。 这按我想要的方式工作。

当服务启动时,我打开消费者一次,并不断轮询消息。

More Info: The server I call is third party and I have no control over what messages it sends. I do know, based on the message ID's that they are put on in the right order. Also, in this system there is a difference between ACK and Acknowledge. The ACK is received when my original message is put on the the "outbound" queue. I then monitor an "inbound" queue for responses. I usually get an "Acknowledge" followed by a "Pass" or a "Fail". The correlation ID for these messages is the message ID from the ACK.

I had originally used a message listener and responded to an OnMessge event. I abandoned this approach after realizing that, using this method, messages are delivered asynchronously and therefore in no particular order. So, I changed my code to poll using a timer (System.Threading.Timer) to call consumer.Receive() and get one message at a time. This works the way I want.

I open the consumer once when the service starts and I continuously poll for messages.

你好,陌生人 2024-07-18 16:06:10

为什么消息顺序很重要? MessageListener 不必关心。

如果您需要关联 ID 来将响应与特定请求相匹配,那就是另一回事了。 你是这个意思吗?

Why is message order important? A MessageListener shouldn't have to care.

If you need a correlation ID to match a response with a particular request, that's another matter. Is that what you mean?

尬尬 2024-07-18 16:06:10

杰森刚才说的一切。 其他一些需要注意的事情。 您让消费者对大量消息保持开放状态,对吧? 您不是为几条消息创建一个消费者然后关闭它吗? 只有关闭消费者才会导致与消费者相关的消息被放回到队列中,这可能会破坏顺序。

与回滚有关系吗? (您是否回滚任何交易?)。

最后,您始终可以使用 Resequencer 为您重新排序,以确保顺序。

Everything Jason just said. A few other things to be careful of. You are keeping the consumer open for lots of messages right? You're not creating a consumer for a few messages then closing it? Only closing a consumer causes messages associated with a consumer to be put back onto a queue which can break order.

Is it related to rollbacks? (Are you rolling back any transactions?).

Finally, you can always ensure order by using a Resequencer to reorder things for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文