2015-01-08 8 views
1

WCF 및 MSMQ를 통해 실행되는 특정 서비스가 있습니다. 모든 것이 잘 작동하지만 한 작업을 처리하는 중에 예상치 못한 일이 발생하면 다른 작업에 영향을주지 않아야한다는 요구 사항이 있습니다. 서비스가 견고하도록 설계되었습니다. 우리는 두 차례의 작업에서 충돌을 경험하지 못했지만 최근에는 고객이 서비스 프로세스를 중단하고 둘 이상의 작업을 잃어버린 것에 대해 불만을 토로했습니다.MSMQ에서 여러 메시지가 제거되었습니다.

조사하려면 200ms마다 큐의 내용을 추적하고 예기치 않은 것을 발견하는 타이머를 추가했습니다. 요청을 처리 할 때 WCF는 대기열에서 둘 이상의 메시지를 제거합니다. 여기 관련 이벤트의 smartinspec 추적의 (중앙 컬럼의 숫자는 스레드 식별자입니다) :

enter image description here

항상 서비스 프로세스 어딘가에서 버퍼 하나의 메시지를 유지할 것으로 보인다. 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> 
+0

이전에이 문제가 발생했습니다. 그것에 대해 할 수있는 일이 없습니다. netMsmqBinding 스택이 작동하는 방법입니다. –

답변

2

입니다. WCF가 처리를 위해 대기열의 여러 메시지를 읽을 수 있다는 것은 사실입니다. 일반적으로 이것은 문제가 아니며 트랜잭션 대기열에서는 문제가되지 않습니다 (각 개별 트랜잭션은 메시지 처리가 완료된 후에 만 ​​커밋하기 때문에 그렇지 않으면 트랜잭션이 중단되고 메시지가 대기열로 반환됩니다) .

기본적으로 트랜잭션을 비활성화하고 비 트랜잭션 대기열을 사용하여 메시지 손실을 방지하는 방식으로 메시지를 처리하지 않도록 선택했습니다. 기본적으로 MSMQ 및 WCF에 말하면 가끔 메시지를 잃어 버리는 것은 문제가 없다고 말씀하셨습니다.

컴퓨터 (또는 MSMQservice)에 충돌이 발생하면 어떤 작업이 발생하는지 고려하십시오. 메시지가 지속되지 않기 때문에 모든 것을 잃을 것입니다.

+0

동의 함. 트랜잭션 대기열을 사용하면 고객이 처리를 유지하는 메시지를 제거하기 위해 더 이상 서비스를 죽일 수 없다는 단점이 있습니다. –

+0

@TomRedfern 나는 이것이 문제가 될 것이라고 생각하지 않지만 우려를 공유해 주셔서 감사합니다. –

+0

Transnational 대기열이 실제로 작동하기 때문에이를 공식 답변으로 표시했습니다. 그러나 트랜잭션 범위가 SQL 트랜잭션을 방해하기 때문에 소프트웨어를 변경하지 않습니다. –