2012-12-21 7 views
4

실제로 메시지를 검색하기 전에 MassTransit 소비자가 MSMQ 대기열을 Peek() 할 수 있는지 궁금합니다.Masstransit consumer death - Peek()

이 단계/프로세스가 무엇 :

1) 메시지가

2) 소비자를 얻을 대기열로 전송 및 DB 갱신을 할 수있다 - 약 5 초

3 소요) 소비자 첫 번째 작업을 수행 한 경우 업데이트의 두 번째 라운드를 수행해야합니다.

문제는 첫 번째 DB 업데이트가 실패하여 메일이 대기열에 머물러있어 (예 : 네트워크 문제이며 데이터베이스에 연결할 수없는 경우) 어떻게 처리 할 수 ​​있습니까?

는 는

현재 즉시이 그것을 제거하고 DB 업데이트가 실패 할 경우 다음 그냥 사라 큐에서 MSG .. 또한

를 읽고, 나는이 정전을 처리 할 수있는 방법을 - 나는 방법 절반 경우 의미 소비자가 '일'을 통해 무엇이든지 (DB 업데이트 또는 다른 것), 전원이 죽으면 어떻게 대기열의 msg에 대한 프로세스를 다시 실행할 수 있습니까? 말하자면 (현재 어쨌든 현재 인스턴스에서) 새 행을 테이블로 밀어 넣고 있다고 가정 해 보겠습니다. 첫 번째 행을 확인하고 코드를 삭제 한 다음 작업을 실행하지 않으면 코드를 작성하여 처음부터 전체 프로세스를 다시 실행할 수 있습니까?

나는 Peek() 대기열을 읽은 다음 작업을 실행하고 실제 대기열 메시지를 읽은 다음 제거한다.하지만 대중 교통과 함께 작동하는지는 알 수 없다. 비트 손실 ...

또한 Masstransit에는 .RetryLater이 있지만 그 과정에서 사용합니까? 그것입니까 Initially ->When ->Then ->.RetryLater 사가에서 ?? 나는 무용담을 사용하고 있습니다 ....

Define(() => 
      { 
       RemoveWhen(saga => saga.CurrentState == Completed); 

       Initially(
        When(NewAC) 
         .Then((saga, message) => saga.ProcessPSM(message), 
          InCaseOf<Exception>() 
           .TransitionTo(Problem)         
           ) 
         .Then((saga, message) => saga.PostProcessPSM()) 
         .Complete() 
        ); 
       During(Problem, 
        When(Waiting) 
           // NOTE: THIS DOES NOT WORK!!!! 
         .RetryLater() 
        ); 
       }); 

RetryLater 중 오류가 발생 :

모든 포인터는

편집

PS가

친절한 감사 로빈

을 appeciated 것 : "기존 무용담으로 메시지를 수락 할 수 없습니다."

다른 방법으로 'RetryLater'에 액세스 할 수 있는지 잘 모르겠습니다.

답변

7

MassTransit은 기본 대기열의 개념을 추상화합니다. 따라서 Peek는 해결책이 아니며 이지만 메시지를 다시 시도하는 다른 방법이 있습니다. 오류 및 장애 조건을 처리하는 데 관심이있는 경우 다음 메커니즘만으로 충분합니다. 기본적

소비자가 메시지를 N 번 시도한다 예외가 발생하는 경우 : N (5)는 버스와 디폴트에 구성된

  • .그것은 ServiceBusConfigurator에 SetDefaultRetryLimit를 사용하여 initilisation 에서 버스를 변경할 수 있습니다
  • 시도
  • 는 처리 작업을 수행 할 수 있습니다 에러 미세한 그레인 접근을하려는 경우 메시지 큐

의 끝에 추가된다는 것을 의미합니다 컨텍스트 소비자를 구현하고, 복구 가능한 또는 일시적인 예외를 잡아서 RetryLater를 수동으로 호출합니다. 내가 이것을 이해할 때 얼마나 많은 시간을 할애 할 수 있는지는 아무런 제한이 없다.

public class RetryConsumer : Consumes<AwesomeMessage>.Context 
{ 

    public void Consume(IConsumeContext<AwesomeMessage> message) 
    { 
     try 
     { 
      Console.WriteLine("This is Attempt " + message.RetryCount); 
      // Do Something 
     } 
     catch (SomeTransientException e) 
     { 
      message.RetryLater(); 
     } 
    } 
} 
+0

감사합니다. 나는 오늘 시험에서 그걸 시도 할 것이다. 그러나 내 질문은 한 가지 경우에 다소 남아 있습니다. 힘의 절반이 죽으면 어쩌지? msg는 더 이상 대기열에 없습니다. 그래서 그것은 잃어버린 것입니까? 소비자가 결코'message.retrylater()'에 도착하지 않기 때문에 ... 이런 경우에 메시지를 재 시도하는 것과 같은 중단 된 프로세스 또는 완전한 실패를 처리 할 수있는 방법이 있습니까? 아니면 위의 무엇인가 놓치고 있습니까? 감사! –

+0

MSMQ와 함께 트랜잭션 큐를 항상 사용할 수 있습니다. 이렇게하면 정전이 발생해도 메시지가 손실되지 않습니다. URI에? tx = true가 있으면 거기에 도달합니다. –

+0

@ChrisPatterson 예 이미 사용하고 있습니다. 메시지를 읽는 시나리오를 다루지는 않는다고 생각합니다. 나는 이것이 단지 대기열에 도착하기를 보장하는 대기열에 '추가'하면 복구 가능이 true로 설정되어 있기 때문에 지속된다고 생각했습니다. 그러나 트랜잭션 설정에 따라 대기열에서 메시지를 읽으면 프로세스를 읽는 프로세스가 해당 작업을 완료하는지 확인할 수 있습니까? 나는 생각하지 않거나 ...? –

관련 문제