使用 Rebus 使用第一级和第二级重试来测试 Handle 和 Handle<IFailed> 方法

Test both Handle and Handle<IFailed> methods with 1st level and 2nd Level Retry with Rebus

如何调试下面的两种 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)像abvoe?

注意:在Handle(string message)内抛出异常时,没有调用IErrorHandler,也没有调用AddTransportMessageForwarder,这些正确吗?

你能试着检查一下你的日志吗?

当你删除rbs2-msg-idheader时,Rebus会立即将消息移动到dead-letterqueue,只是拒绝处理它。这是因为没有消息 ID 的消息无法被 Rebus 的错误跟踪器跟踪。

如果删除 rms2-msg-type header,序列化程序很可能会抛出错误并且不会反序列化传入消息。

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

在这两种情况下,消息 body(在本例中为 string,但它可以是任何消息类型) cannot be constructed from the incomingbyte[], so Rebus cannot dispatch the message as eitherstringnotIFailed`.

更新 1 后编辑:

如果您的第 2 级重试没有启动,很可能是因为您没有启用它们:

Configure.With(...)
    .(...)
    .Options(o => o.SimpleRetryStrategy(secondLevelRetriesEnabled: true))
    .Start();

IErrorHandler 在将消息移动到 dead-letter queue 时调用。当所有投递尝试都失败时(5 次正常投递尝试 + 5 次二级投递尝试),您应该会看到它被调用。

如果您按照我建议的方式配置,AddTransportMessageForwarder 用于另一个总线实例,该实例接收来自 error queue 的消息。当 IErrorHandler 被调用,失败的消息被转发到 queue error,那么你的传输消息转发器应该被调用。