首页 > 解决方案 > RabbitMQ - 处理不可靠的服务

问题描述

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

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

标签: rabbitmqpollyretry-logicreliable-message-deliveryunreliable-connection

解决方案


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

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

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

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

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

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


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


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


推荐阅读