1

我有一项通过 WCF 和 MSMQ 运行的服务。一切正常,但我们有一个要求,即如果在处理一项工作期间发生意外情况,它不应影响其他任何工作。该服务被设计成健壮的,而且确实如此。我们在两年的运营中从未发生过崩溃,但最近我们的客户喜欢终止服务流程并抱怨不止一份工作丢失。

为了进行调查,我添加了一个计时器,它每 200 毫秒跟踪一次队列的内容,并发现了一些意想不到的东西。处理请求时,WCF 从队列中删除多条消息。这是相关事件的 smartinspec 跟踪(中心列中的数字是线程 ID):

在此处输入图像描述

它似乎总是在服务进程的某个地方缓冲一条消息。我一直在查看 WCF 文档,但没有找到任何关于这种行为的参考我可以做些什么来防止这种缓冲,或者你可以让我参考一些相关的文章吗?

这是服务类:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
 public class TheService : ITheService
 {
   private readonly ITraceFacade trace = TraceFactory.Resolve();//for tracing

   public ClientCodeWrapper clientCodeWrapper { get; set; }// a wrapper for libraries written by our client. it's instantiated and set in the OnStart method of the service host class

   public void ProcessJob(long jobId)
   {
      using (this.trace.ActivityScope(string.Format(CultureInfo.InvariantCulture, "The Service.ProcessJob({0})", jobId)))
       {        
         this.clientCodeWrapper.ProcessJob(jobId);        
       }
    }    
 }

这是我的服务配置

<system.serviceModel>
  <bindings>
    <netMsmqBinding>
      <binding name="MsmqBindingNonTransactionalNoSecurity" exactlyOnce="false">
        <security mode="None"/>
      </binding>
    </netMsmqBinding>
  </bindings>

  <services>
    <service name="TheService">
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:8080/TheServiceIn"   />           
        </baseAddresses>
      </host>           
      <endpoint address="net.msmq://localhost/private/TheServiceIn"  
              binding="netMsmqBinding"
              bindingConfiguration="MsmqBindingNonTransactionalNoSecurity" 
              contract="ITheService">         
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>       

      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
  </services>
</system.serviceModel>
4

1 回答 1

2

你所看到的似乎只是我所期待的。确实,WCF 可以读取队列的多条消息进行处理。通常,这不是问题,对于事务队列,这绝对不是问题(因为每个单独的事务只会在消息处理完成后提交,否则事务将中止并将消息返回到队列) .

因此,基本上,您选择不以通过禁用事务和使用非事务队列来避免丢失消息的方式处理消息。基本上,您告诉 MSMQ 和 WCF,偶尔丢失消息是完全可以的。

考虑一下如果您的机器(或 MSMQ 服务)崩溃会发生什么:您不会只丢一份工作;你会失去所有这些,因为消息不会被持久化。

于 2015-01-08T13:12:49.727 回答