Masstransit消费者死亡 - Peek()

时间:2012-12-21 03:55:12

标签: masstransit

我很好奇MassTransit消费者在实际检索msg之前是否可以Peek()MSMQ队列。

步骤/过程是什么:

1)Msg发送到队列

2)消费者得到它并且必须进行数据库更新 - 大约需要5秒

3)如果第一轮更新,消费者必须进行第二轮更新。

我的问题是,如何处理如果第一个数据库更新失败,消息留在队列中(即网络问题而无法访问数据库)的情况。

目前,只要它从队列中读取消息,就会将其删除,然后如果数据库更新失败,它就会消失。

此外,我如何处理电源故障 - 我的意思是如果消费者通过“工作”的一半,无论是(db update或其他什么)和电源芯片等,我该如何重新运行队列中的msg进程?让我们说这个工作(无论如何我当前的实例)正在推动一个新的行到一个表。我的意思是我可以编写代码来首先检查行是否存在,然后是否删除消息,如果没有则运行任务,但是如何才能让它重新运行整个过程呢? / p>

我已经读过我可以Peek()队列,然后运行任务,然后读取队列消息真实并删除它,但我不能为我的生活弄清楚是否适用于公共交通......有点失落......

另外我知道Masstransit有.RetryLater但是我在这个过程中使用它吗?是Initially - > When - > Then - >传奇中的.RetryLater

任何指针都会被指定

最基本的问候 罗宾

修改

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抛出错误: “现有的传奇故事不能接受这条消息”

我不确定我还能如何访问'RetryLater'。

1 个答案:

答案 0 :(得分:7)

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

默认情况下,如果使用者抛出异常,则会重试N次消息:

  • 其中N在总线上配置,默认为5.可以更改 使用ServiceBusConfigurator上的SetDefaultRetryLimit进行总线初始化
  • 重试的地方意味着消息将被添加到队列的末尾

如果您想要一种更细粒度的错误处理方法,您可以实现Context Consumer,捕获可恢复或瞬态异常并手动调用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();
        }
    }
}