【问题标题】:MassTransit consumer fault handling when the destination system is down for long time目标系统长时间停机时的 MassTransit 消费者故障处理
【发布时间】:2020-09-14 05:33:52
【问题描述】:

我已经阅读了有关错误处理和故障的 MT 文档,并放置了一些代码来发布故障,并编写了一个故障使用者来在使用 Polly 重试几次后收听故障消息。

我有一个队列消费者使用 MassTranasit 从 RabbitMQ 获取消息并通过 Http api 发送到云系统。我已经处理了所有可能的异常,并且还在 Polly retry 中包装了 http 调用,以解决暂时的网络错误。但是这种方法的问题是,在重试用尽后,消息实际上会被放弃处理。

假设目标系统停机 10 小时(我们之前不知道这种中断,否则我将计划停止消费者服务),我们可以使用 MassTransit 停止将消息从队列拉入的最佳策略是什么消费者?有没有办法根据失败次数等停止接收消息?

谢谢

【问题讨论】:

  • 您应该使用 MassTransit 的重试支持,而不是下面 Alexey 所述的“polly”,并且您应该进行监控以检测这些错误(从日志中)并停止服务以避免循环通过每条消息队列只需要在服务可用后将它们铲回队列(来自_error)。
  • 嗨,克里斯,感谢您的评论。您能否在下面的 Alexey 回复中查看我关于使用 Polly 而不是 MT 重试的评论?这有意义吗?
  • 我支持 Chris 关于监控的观点。如果你抽象出远程系统客户端并使用健康检查来观察它的行为,你也可以让你的服务不健康并从外部处理它。

标签: rabbitmq masstransit


【解决方案1】:

您需要一个断路器,这是分布式系统中众所周知的模式。当远程系统在负载下挣扎并且向它发出更多请求时,断路器会激活,这可能会扼杀它。它还允许您在远程系统关闭时停止向其发送消息。

断路器是开箱即用的available in MassTransit

我也不建议在消费者中使用 Polly 实现重试。 MassTransit 有一套全面的重试策略,它还允许 MassTransit 了解消费者中发生了多少故障,这在您使用 Polly 时不可用。例如,断路器中间件不会知道 Polly 包装调用中的故障,因此不会做出正确反应。

如果远程系统长时间停机(如您所描述的几个小时),任何尝试次数有限的重试策略最终都会失败。断路器将打开,但它会不时重置并尝试再次发送呼叫消费者。否则,它永远不会知道远程系统何时恢复。因此,您要么需要从错误队列中恢复消息,要么添加 redelivery 中间件。

因此,您可以这样配置接收管道:

重新交付 -> 断路器 -> 重试 -> 消费者

【讨论】:

  • 嗨,Alexey,感谢您的回复。我有理由使用 Polly 而不是 MT 消息重试,使用 MT 重试,消费者中的整个代码每次都会执行,我只知道我需要重试的代码是在最后一点和任何地方对目标系统的传出 http 调用否则,如果我遇到异常,则无法通过重试来解决。那么使用 Polly 是否有意义,或者您仍然强烈建议在这里使用 MT 重试?谢谢
  • 还有关于重试,就像你提到的,我们在这里有几个选择。 1. 使用 _Error 队列并稍后手动将它们移回正常队列 2. 使用 RabbitMQ 延迟计划在一定时间后重新传递。我喜欢这个时间表,但我不确定安排消息的确切时间,因为目标系统中断不在我们手中。你觉得哪一个更好?
  • 我明白了。您可以选择将绑定到 HTTP 调用的操作拆分到单独的使用者中,并从原始使用者向您自己发送消息。关于重新交付以及重试,您可以配置增量或指数重试,因此重试之间的超时会增加,只要确保它不会过长。如果你想坚持使用 Polly,你也可以使用 Polly 自己的断路器。基本上,断路器就是你所需要的,你只需要找出你想在哪个级别应用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多