使用Rebus进行第1级和第2级重试来测试Handle和Handle <ifailed>方法

时间:2019-05-27 14:58:43

标签: rebus rebus-azureservicebus

如何调试下面的两个Handle方法?

我在Visual Studio中的两个Handle方法上都设置了断点,并将消息发送到Subscriber1队列中,但是在VS中没有调用这两个方法。

public class SomeHandler : IHandleMessages<string>, IHandleMessages<IFailed<string>>
{
    readonly IBus _bus;

    public SomeHandle(IBus bus)
    {
        _bus = bus;
    }

    public async Task Handle(string message)
    {
        // do stuff that can fail here...
    }

    public async Task Handle(IFailed<string> failedMessage)
    {
        await _bus.Advanced.TransportMessage.Defer(TimeSpan.FromSeconds(30));
    }
}

下面是发送到Subscriber1的邮件。

我尝试发送不包含rbs2-msg-idrbs2-msg-type的消息,但它们都不触发上面的Handle方法。

{
  "body": "Test",
   //other fields
  "properties": {
    "rbs2-intent": "pub",
    "rbs2-msg-id": "cd57d735-3989-45b5-8a3c-e457fa61dc94",
    "rbs2-return-address": "publisher",
    "rbs2-senttime": "2019-05-27T15:07:25.1770000+01:00",
    "rbs2-sender-address": "publisher",
    "rbs2-msg-type": "System.String, mscorlib",
    "rbs2-corr-id": "cd57d735-3989-45b5-8a3c-e457fa61dc94",
    "rbs2-corr-seq": "0",
    "rbs2-content-type": "application/json;charset=utf-8"
  },
  //other fields
}

更新1

如果在Handle(string message)中引发了异常,则将根据第一级尝试次数重试该方法。这就是我们所需要的。

但是,Handle(IFailed<string> failedMessage)没有被调用,如何像从前那样调试Handle(IFailed<string> failedMessage)

一个笔记:当在Handle(string message)中引发异常时,不调用IErrorHandler,也不调用AddTransportMessageForwarder,这些对吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试检查日志吗?

当您删除rbs2-msg-id标头时,Rebus会立即将邮件移至死信队列,只是拒绝处理它。这是因为Rebus的错误跟踪器无法跟踪没有消息ID的消息。

如果删除rms2-msg-type标头,则序列化程序很可能会引发错误,并且不会反序列化传入的消息。

在两种情况下,错误都会输出到记录器。

在两种情况下,消息正文(在这种情况下为string,但可以是任何失败的消息类型) cannot be constructed from the incoming字节[] , so Rebus cannot dispatch the message as either字符串not

更新1 后编辑:

如果您没有进行第二级重试,则很可能是因为您尚未启用它们:

Configure.With(...)
    .(...)
    .Options(o => o.SimpleRetryStrategy(secondLevelRetriesEnabled: true))
    .Start();
当需要将消息移至死信队列时,将调用

IErrorHandler。当所有传递尝试均失败(5次正常传递尝试+ 5次第二级传递尝试)时,您应该会看到它被调用。

如果按照我的建议配置事物,则AddTransportMessageForwarder用于另一个总线实例,该总线实例从error队列接收消息。当调用IErrorHandler,并且失败的消息已转发到队列error时,则应该调用您的传输消息转发器。