RabbitMQ - 处理不可靠的服务

Tes*_*t45 1 unreliable-connection rabbitmq reliable-message-delivery polly retry-logic

我有一个服务 AAA,每分钟向 RabbitMQ 交换发布 10 到 5 万条消息。.NET Core 服务 BBB 订阅一个队列(所有消息都路由到该队列),并为每条消息调用另一个通过 Internet 的 HTTP 服务 CCC。问题是 CCC 非常不可靠,每天有几次它会完全关闭一两分钟,每周至少有一次它会关闭一个小时。

我无法控制 AAA 或 CCC。如何使用 RabbitMQ 路由功能可靠地传递所有消息?

mou*_*ler 6

对于不可靠的第三方服务 CCC(离线数分钟或数小时),断路器可能很有用。配置断路器检测到CCC离线时分断。

您可以监控断路器状态以检测 CCC 何时离线和/或记录电路状态的变化以供以后分析。

Polly 的断路器允许您在电路状态转换上挂钩任何自定义代码,因此您还可以:

  • 当电路中断时,从 RabbitMQ 队列取消订阅。
  • 当电路半开时,以窄并行度重新订阅 RabbitMQ 队列(例如,预取计数只有 1 或 2 ...只有足够的消息供断路器重试电路)。
  • 当电路关闭(再次正常)时,以全吞吐量重新订阅 RabbitMQ 队列。

一旦断路器检测到 CCC 离线,此模式将阻止您获得 100000 条消息流向 RabbitMQ 错误/死信/您的自定义重试队列。

您仍然需要考虑失败的消息(在电路中断之前或重新测试时)会发生什么,如另一个答案中所述。将它们定向到错误/重试队列。或者,如果 CCC 关闭时取消订阅模式与您的现实世界参数配合得很好,您也许可以让失败的消息简单地返回到原始队列。


如果 CCC 还遇到任何暂时性故障(故障仅几秒钟),请考虑引入WaitAndRetry 策略


由于传入消息速率可能为每秒 1000 秒,您可能需要考虑如何限制BBB 内消息处理的并行性和/或对 CCC 调用设置的超时。如果没有这个,您可能会面临消费者内存膨胀的风险,因为越来越多的消息到达,而其他请求在超时之前挂在 CCC 的响应上;CCC 上的高超时显然会加剧这种情况。消费者并行性可以通过使用手册ack和应用pre-fetch count.