2012-12-21 39 views
4

我很好奇,如果MassTransit消费者可以真实的检索味精之前PEEK()一个MSMQ队列。Masstransit消费者死亡 - 皮克()

什么步骤/过程是:

1)消息发送到队列

2)消费者得到它,必须做一个数据库更新 - 大约需要5秒钟

3)消费者必须做第二轮更新如果第一次工作。

我的问题是,我该怎么处理的情况下,如果第一DB更新失败的消息停留在队列(即网络问题,无法得到分贝)。

目前只要它读取它消除它,如果数据库的更新失败,那么它只是消失在队列中的味精..

此外,我怎么能处理停电 - 我的意思是,如果一半通过“工作”,由消费者,不管它是什么(DB更新或别的东西)和功率等死,我怎么能在队列中的味精重新运行的过程?让我们说这份工作(无论如何,我目前的实例)正在推动一个新的表格。我的意思是,我可以编写代码来第一次检查,如果该行是存在的,如果是则丢弃该消息,如果没有的话运行任务,但我怎样才能在第一时间就重新运行的全过程?

我已经读了,我可以Peek()队列,然后运行任务,然后阅读真正的队列消息,并删除它,但我不能为我的生活弄清楚,如果这与公共交通的工作... ...有点失落......

另外据我所知,Masstransit具有.RetryLater却对我使用的过程中?它是Initially - >When - >Then - >.RetryLater的传奇?

任何指针将appeciated

最亲切的问候 罗宾

编辑

PS:我用的是传奇....

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抛出的错误:

“该消息不能由现有的传奇接受的” 10

我不知道我还能怎么访问“RetryLater”。

回答

7

MassTransit抽象底层队列的概念。所以Peek并不是解决方案,但它确实有其他方法来重试消息。如果您只是对处理错误和故障条件感兴趣,以下机制就足够了。

默认情况下如果消费者抛出异常的消息将被重试N次:

  • 其中n是总线,默认上配置为5。它可以在 改变总线initilisation使用的ServiceBusConfigurator SetDefaultRetryLimit
  • 凡重试意味着信息将被添加到队列

结束时,如果你想更细粒度的方法错误处理,你可以实现一个上下文消费者,捕获可恢复或暂时的异常并手动调用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

谢谢队友。今天我会试一试。然而,我的问题在一个案例中仍然存在。如果在权力的一半中死去会怎么样?味精不再在队列中。所以它失去了是的?因为消费者永远不会去'message.retrylater()'...有没有办法处理挂起的进程或完成的失败,就像在那种情况下稍后重试消息一样?还是我错过了上面的东西?谢谢! –

+0

您始终可以使用MSMQ的事务队列,这可以确保在电源故障情况下邮件不会丢失。在URI上的tx = true可以让你在那里。 –

+0

@ChrisPatterson是的,我已经在使用它。我不认为这包括阅读信息的情况。我认为这只是保证,如果你'添加'到队列中,它保证进入队列,然后因为可恢复设置为真,持久。但是,事务设置是否也确保当我从队列中读取消息时,读取​​它的进程完成其工作?我认为不是或...? –

相关问题