RabbitMQ暂时关闭时的重试重试策略

时间:2020-07-31 13:44:07

标签: rebus rebus-rabbitmq

我有一个dockerized微服务架构,在其中我将Rebus与RabbitMQ用作消息总线。

一个容器正在运行RabbitMQ。其他容器正在运行通过Rebus / RabbitMQ相互通信的服务。

我希望我的解决方案能够适应容器重启,因此,例如,如果RabbitMQ容器重启,则我希望其他服务不会受到影响。 我希望RabbitMQ关闭时发送的消息会排队等待Rebus传递 在发送服务中,并在RabbitMQ连接恢复时将其交付。

要验证我是否运行此测试方案:

  1. 服务A通过Rebus和RabbitMQ向服务B发送一条消息。很好。
  2. 我停止RabbitMQ容器。
  3. 服务A通过Rebus和RabbitMQ向服务B发送一条消息。失败是因为RabbitMQ不可用。
  4. 我再次启动RabbitMQ容器。
  5. 我可以看到服务中的Rebus在启动时会自动重新连接到RabbitMQ。符合预期。
  6. 现在,RabbitMQ连接已恢复,我希望Rebus将未决消息从服务A发送到服务B,但不会。

这不是Rebus的预期行为吗?如果没有,我可以启用此功能吗?

我已经阅读了本主题https://github.com/rebus-org/Rebus/wiki/Automatic-retries-and-error-handling 并尝试像这样配置Rbus:

Configure.With(...)
    .Options(b => b.SimpleRetryStrategy(maxDeliveryAttempts: 10))
    .(...)

但没有运气。

1 个答案:

答案 0 :(得分:1)

您正在配置的“传递尝试”是如何配置在放弃之前将多少Rebus尝试使用已接收的消息(即,将其移至错误队列)。

如果Rebus失去与代理的连接,它将无法在整个中断期间接收任何信息,因此停止RabbitMQ应该有效地暂停所有消息处理(可能在瞬间处理的所有消息中可能有一些例外) RabbitMQ消失的地方。

由于届时将没有Rebus处理程序运行,而RabbitMQ处于关闭状态,则您将不得不处理从其他地方发送的传出消息,例如例如通过网络请求发送/发布的消息。

(...)我希望RabbitMQ关闭时发送的邮件会排队等待Rebus(...)

传递

...但是Rebus无法将任何队列排队,因为RabbitMQ已关闭(*)。

在这种情况下,对Rebus来说很自然的事情是让您(呼叫者)有责任决定如何解决问题。

在.NET中,通常通过向您抛出异常来实现。 ?

这使您可以选择

  • 执行一些其他操作,或者
  • 再试几次,或者
  • 在特定情况下有意义的一切

在这种情况下,在系统中建立一定弹性的一种简单方法是使用类似Polly的方法,尝试多次发送传出邮件,以防失败。

我希望这是有道理的。请让我知道是否需要详细说明。 ?


(*)当然,Rebus可能会“欺骗”并在内存中排队外发消息,但这将使您很难编写弹性代码,因为您不知道外发消息是否已安全传递到经纪人,还是只是坐在内存中等待保存在某处。