NetMsmqBinding:正在多次处理消息

时间:2013-02-25 19:11:10

标签: .net wcf msmq message-queue transactionscope

我的团队有一个使用http绑定托管wcf服务的Windows服务。当wcf服务收到消息时,它会立即使用NetMsmqBinding将其发送到另一个wcf服务,该服务也托管在Windows服务中。 msmq服务处理消息并将其保存到我们的数据库中。

在开发和登台环境中,一切正常。当我们部署到生产时,我们看到发送到我们服务的消息乘以系数n + 1(对于n个消息)。

例如:收到1条消息,2条保存到DB。收到4条消息,20条保存到DB等。

我们怀疑它与交易的msmq服务设置有关,

并发和InstanceContextMode,但我们无法弄明白。

服务的设置为:

  • InstanceContextMode:默认。
  • ConcurrenyMode:默认
  • 交易:TransactionScoreRequired = True且TransactionAutoComplete = True。
  • RetryCount = 1,RetryCycles = 1

我们使用.Net 4,MSMQ 3.0和Windows Server 2003。

对可能导致此问题的任何想法?

编辑:

经过大量研究,我们发现了以下几点:

  • 当wcf运行时尝试为单个消息提交事务时,它会抛出异常“事务已异步中止”。每次重复邮件时都会抛出此异常。
  • 在wcf跟踪中,我们没有看到除上述情况之外的任何异常。
  • 在System.Transaction跟踪中,我们看到正在打开一个事务(对于第一条消息),然后在wcf运行时创建该事务的克隆(具有属性RollbackIfNotCompleted = true)之后,几秒钟没有通过跟踪中没有消息,然后再次发生相同的事情。

我们真的很无能......

由于

2 个答案:

答案 0 :(得分:3)

除非您的应用程序将其删除或TimeToBeReceived计时器到期,否则MSMQ不会删除邮件。

如果我正确理解了您的环境,则问题可能是由于收到的邮件处理时间过长造成的。如果在同一事务中完成消息的接收和重新发送,则第一个WCF服务可能会在最终从队列中删除之前多次尝试读取同一消息。

这引导我尝试以下想法:

  • 您可以在收到原始邮件后尝试创建具有相同内容的新邮件,并将新邮件发送到下一个WCF服务。这应该缩短收到消息的生命周期。

  • 如果您需要保留相同的消息顺序,可以尝试将Miker169的配置更改为InstanceContextMode.Single , ConcurrencyMode = ConcurrencyMode.Singlehttps://stackoverflow.com/a/2610093/219344

答案 1 :(得分:2)

好吧,我们终于明白了: 我们使用Entlib进行日志记录,并添加了一个DB侦听器。 Entlib数据库侦听器使用该服务的相同事务。当它尝试将事务传递给数据库服务器时,会引发错误,因为在数据库服务器上未正确配置MSDTC,这会导致事务回滚。当WCF运行时尝试提交事务时,它会因为已经中止而失败,然后它再次尝试处理相同的消息(因为内置的重试机制)。

当我们修复MSDTC设置时,复制停止 现在,我们需要弄清楚的是:为什么回滚到服务事务会导致消息成倍增加?