我有一个使用ActiveMQ客户端的.NET服务。我已经实现了一个带有事务连接的MessageListener来使用消息。
有时候,我会按照不同的顺序获取邮件。
使用MessageListner是不是错了?有没有办法保留邮件订单?
仅供参考:有一个生产者将消息放入队列,一个消费者将消息从队列中拉出来。
答案 0 :(得分:1)
你不应该做任何事来维持秩序;这是消息队列为您做的事情之一。我认为,如果你有一个消费者正在侦听队列,并且它正在处理无序的消息,那么你要么发现了一个错误,要么消息没有按照你认为的顺序排列。
此外,this question中的ActiveMQ FAQ可能有所帮助。
修改:通过阅读duffymo's answer上的评论,您看起来有点过度工程了。通常,像ActiveMQ,MQ Series,joram等消息队列有两个特征:它们按照排队的顺序传递消息,并保证消息传递。发送单独的ACK消息是多余的;这有点像提交数据库事务,然后再查询相同的信息,仔细检查数据库实际存储它。
话虽如此,您的服务器是多线程的吗?如果是这样,它可能会将响应排入之前,它会使ACK排队。
答案 1 :(得分:1)
更多信息:我呼叫的服务器是第三方,我无法控制它发送的消息。我知道,根据消息ID,它们以正确的顺序放置。此外,在该系统中,ACK和Acknowledge之间存在差异。当我的原始消息放在“出站”队列上时,会收到ACK。然后我监视一个“入站”队列以获得响应。我通常得到一个“确认”,然后是“通过”或“失败”。这些消息的相关ID是来自ACK的消息ID。
我最初使用过消息侦听器并响应了OnMessge事件。我意识到,使用这种方法,消息是异步传递的,因此没有特定的顺序,我放弃了这种方法。因此,我将我的代码更改为使用计时器(System.Threading.Timer)调用来调用consumer.Receive()并一次获取一条消息。这按照我想要的方式工作。
我在服务启动时打开消费者一次,并不断轮询消息。
答案 2 :(得分:0)
为什么消息顺序很重要? MessageListener不应该关心。
如果您需要相关ID来匹配具有特定请求的响应,那么这是另一回事。这是你的意思吗?
答案 3 :(得分:0)
杰森刚才说的一切。还有一些需要注意的事情。您是否让消费者对大量消息保持开放?您是不是为了几条消息创建消费者然后关闭它?只有关闭消费者才会导致与消费者相关联的消息被放回到可能破坏订单的队列中。
它与回滚有关吗? (你回滚任何交易吗?)。
最后,您始终可以使用Resequencer为您重新排序,以确保订单。