使用通知在 NServiceBus 可恢复性失败时发送消息

Send Message when NServiceBus Recoverability fails using Notifications

当一条消息用完重试次数并移至错误队列时,如何发送消息(或发布事件)?

当一个请求进入我的系统时,我创建一个 Saga 来跟踪它。 Saga 向处理程序发送命令以执行异步工作。如果处理程序失败,我想将该命令移动到错误队列(默认行为)并向 Saga 发送消息以提醒最初请求工作的客户端。

我已经尝试自定义可恢复性行为以将 Saga 用作错误队列,它会发回命令但不会将其放入错误队列:

recoverability.CustomPolicy((config, context) =>
{
    // invocation of default recoverability policy
    var action = DefaultRecoverabilityPolicy.Invoke(config, context);

    if (action is MoveToError)
    {
        return RecoverabilityAction.MoveToError("SagaEndpoint");
    }

    return action;
});

我尝试的另一件事是使用行为挂接到管道,但似乎没有办法覆盖“移至错误队列”步骤。我可以在 await next(); 周围创建一个 IIncomingLogicalMessageContext 和 try/catch,但这会在每次重试时触发,而不仅仅是最后一次重试。我还尝试了 IOutgoingLogicalMessageContext,但是当消息移动到错误队列时不会调用它。如果我遗漏了什么,这可能是一个解决方案。

我也知道我可以在 Saga 中使用超时来猜测 Handler 何时失败。但我宁愿不等待超时,如果失败是快速的,或者如果工作花费的时间比预期的要长,我宁愿冒超时的风险。

我发现 这听起来像是在问同样的事情,但答案不完整并且使用旧的 EventHandler 通知而不是新的基于任务的通知。如果有一种方法可以从通知回调中访问 IMessageSessionIEndpointInstance,我认为这对我也适用。

没有一种“简单”的方法可以做到这一点,因为在发生可恢复性的那一刻,与传入消息相关的任何事务(这对于每种传输都是不同的)都是有疑问的,所以你不能真正做到任何其他在当时发生的事情范围内的任何事情。

启动端点后,您可以将 IEndpointInstance 转换为 IMessageSession(没有像 Stop 方法一样的东西),然后将其分配给您的“错误队列通知程序”所在的位置" 就能找到它。然后,您对 IMessageSession 执行的任何操作基本上都是一个单独的上下文,与传入消息的处理断开连接。

请注意,如果消息由于队列的潜在问题而无法处理,则不会正确报告。这就是为什么大多数人会在这些回调中对 reporting/diagnostics 服务进行某种调用。