【问题标题】:RabbitMQ - deal with unreliable serviceRabbitMQ - 处理不可靠的服务
【发布时间】:2018-08-31 16:41:28
【问题描述】:

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

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

【问题讨论】:

    标签: rabbitmq polly retry-logic reliable-message-delivery unreliable-connection


    【解决方案1】:

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

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

    Polly 的断路器允许您hook in any custom code on transitions of circuit state,因此您还可以:

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

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

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


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


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

    【讨论】:

      【解决方案2】:

      假设你在AAA中的订阅方式是同步的,抛出异常会导致Rabbit将消息放入死信队列。从那里您可以将它们移回或手动检查它们。或者,您可以将其重新发布到同一个交换器,但您可能会遇到故障转移和过度填满队列的消息的问题。为避免这种情况,请使用可防止其再次进入原始队列的标头发布它。创建另一个使用新标头作为过滤器的持久队列。 Presto,你有一个重试队列。您可以订阅它以进行重试和/或警报,使用 Shovel 将消息移回原始队列,等等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-28
        • 1970-01-01
        • 2014-05-24
        • 1970-01-01
        • 2020-02-27
        • 2018-04-23
        • 2015-12-18
        相关资源
        最近更新 更多