两次接收相同的 MSMQ 消息?

Posted

技术标签:

【中文标题】两次接收相同的 MSMQ 消息?【英文标题】:Receiving the Same MSMQ Message Twice? 【发布时间】:2010-10-30 17:36:38 【问题描述】:

我有一个基于 MSMQ 的系统,它具有相互通信的三层。为简单起见,我将它们称为第 1、2 和 3 层。它们的位置如下:

Layer 1 <-> Layer 2 <-> Layer 3

所以第 1 层仅与第 2 层对话,第 3 层仅与第 2 层对话,第 2 层与其他两个对话。为此,我有四个队列,

Layer1_in
Layer1_out
Layer3_out
Layer3_in

各层通过此基础设施进行通信:

Layer 1 -> Layer1_out -> Layer 2
Layer 1 <- Layer1_in <- Layer 2
Layer 3 -> Layer3_out -> Layer 2
Layer 3 <- Layer3_in <- Layer 2

(对不起,如果这比必要的更详尽)

无论如何,一条消息从第 1 层传递到第 2 层,进行一些处理,然后将另一条(相关)消息发送到第 3 层,反之亦然。我遇到的问题是,有时我有两条消息从第 1 层发送到第 2 层,但不是按顺序接收两条消息,而是两次接收第一条消息。我在Layer1_out 上使用BeginReceive 来异步接收消息。完成后,我处理收到的消息并再次致电BeginReceive 以获取下一条消息。

为了追踪这一点,我在发送端实现了一个消息计数器,并将其写入一个文本文件。我正在使用Extension 属性来存储此消息号的字符串表示形式,以便我可以在处理端检索消息号。当我收到一条消息时,我将这个号码写入另一个文件。这应该生成两个具有相同内容的文件,但我会看到类似

00000000000000000214
00000000000000000215
00000000000000000215 <- this is bad!
00000000000000000217
00000000000000000218
00000000000000000219

在回执日志中,表明消息 215 被处理了两次,而 216 没有通过。就我的目的而言,两次处理同一条消息不会对我造成任何影响(因此有一段时间没有注意到这一点),但完全丢失一条消息是一个大问题。

有什么想法吗?

【问题讨论】:

听起来很像 Raymond Chen 最近的帖子blogs.msdn.com/oldnewthing/archive/2009/05/22/9634511.aspx @Ant:有趣的阅读,但我不知道它对这个问题有多大影响,因为我自己没有做任何明确的线程同步(可能在引擎盖下做了一些事情) MSMQ 库,但我对此无法控制或了解)。也许我错过了一些东西......你知道这如何应用吗? 您是否有多个线程在任一侧发送/接收数据?也许一个线程正在覆盖另一个线程的数据。 @Justin:不明确,不。但是,我想我可能已经发现了这个问题;我目前正在测试,假设此修复有效,我将发布答案。 【参考方案1】:

问题解决了......我想有一天我会发布多线程建议,然后我自己就会被违规咬到!

罪魁祸首是这一行:

receiveResult = <queueName>.BeginReceive()

当我有另一条消息已经在队列中等待时,我的ReceiveCompleted 事件在另一个线程上触发并在BeginReceive 的返回值实际写入receiveResult 变量之前到达我的EndReceive(receiveResult) 调用.结果,我用相同的值调用EndReceive 并再次收到相同的消息!围绕同步对象锁定整个事件处理程序可以解决这个问题。

【讨论】:

receiveResult 变量是否在所有线程之间共享?为什么你不在ReceiveCompleted 事件参数中使用AsyncResult 来结束接收?

以上是关于两次接收相同的 MSMQ 消息?的主要内容,如果未能解决你的问题,请参考以下文章

MSMQ 接收事务 - 回滚不再使消息可用

websocket接收消息再发送会发送两次

消息驱动 Bean 两次读取相同的消息

如何防止 Azure webjob 同时多次处理相同的消息

基于托管 SIP 应用程序 API 构建的第二个 Lync 应用程序未接收 SIP 消息

pubSub Source:两次收到相同的消息