Rabbitmq 在消息传递系统中立即多次重试有什么意义?

Rabbitmq 在消息传递系统中立即多次重试有什么意义?,rabbitmq,message-queue,nservicebus,messaging,Rabbitmq,Message Queue,Nservicebus,Messaging,我最近一直在阅读消息传递系统,并专门研究了和。据我所知,如果消息因某种原因失败,它会立即重试多次。这两个系统都提供了稍后重试的可能性,例如在5秒钟内。当五秒钟过去后,信息会再次发送多次 我引用沃恩·弗农的话(第502页): 处理此问题的另一种方法是简单地重试发送,直到成功为止,可能使用一个限制指数回退。对于RabbitMQ,重试可能会失败很长一段时间。因此,结合使用消息NAK和重试可能是最好的方法。尽管如此,如果我们的流程每五分钟重试三次,这可能就是我们所需要的 对于NServiceBus,这称

我最近一直在阅读消息传递系统,并专门研究了和。据我所知,如果消息因某种原因失败,它会立即重试多次。这两个系统都提供了稍后重试的可能性,例如在5秒钟内。当五秒钟过去后,信息会再次发送多次

我引用沃恩·弗农的话(第502页):

处理此问题的另一种方法是简单地重试发送,直到成功为止,可能使用一个限制指数回退。对于RabbitMQ,重试可能会失败很长一段时间。因此,结合使用消息NAK和重试可能是最好的方法。尽管如此,如果我们的流程每五分钟重试三次,这可能就是我们所需要的

对于NServiceBus,这称为第二级重试,当重试发生时,它会发生多次

为什么它需要发生多次?为什么不每五分钟重试一次?五分钟后第一次重试失败,而第二次重试(可能仅几毫秒后)成功的几率有多大


如果由于某些配置而不需要重试(是吗?),为什么我发现的所有示例都有多次重试?

存在第一级重试,以补偿网络和数据库锁定等快速问题。这在NSB中是可配置的,因此如果您不需要它们,可以将其关闭。第二级重试是为了补偿较长的停机时间。例如,我们使用单反来补偿每晚同时回收的数据库

OOTB功能增加了单反之间的持续时间,因为它假设如果上次不工作,您将需要更多的时间来修复它。存在可覆盖的重试策略,因此您可以更改单反的工作方式


在NSB中,FLR总是排在第一位,除非FLR之后事务仍然失败,否则SLR不会发挥作用。此外,您可以完全禁用单反,并构建自己的自定义故障管理器,该管理器还具有其他功能。我们有一个流程,在该流程中,我们有一个故障管理器,负责将问题发送给有人员的帮助台,因为这是解决特定问题子集的唯一方法。

我的背景是NServiceBus,因此我的答案可以用这些术语表达

对于非常短暂的错误,第一级重试非常有效。死锁就是一个很好的例子。您试图更改数据库,而您的事务被选为死锁受害者。在这些情况下,第一级重试是完美的。大多数情况下,您只需要一次第一级重试。如果数据库中存在大量争用,可能2到3次重试就足够了

第二级重试用于不太短暂的错误。想象一下web服务关闭10秒,或者故障转移集群中的SQL Server数据库切换,这可能需要30-60秒。如果您在几毫秒后重试,这对您没有任何好处,但10、20、30秒后您可能会有一个好机会

然而,问题的关键是在5次一级重试之后,然后是一次延迟,为什么要在额外延迟之前重试5次

首先,在第一次第二级重试时,仍然可能出现死锁或其他非常短暂的错误。毕竟,目标通常不是使系统尽可能慢,因此如果问题确实是暂时的,最好不要在重试之前等待额外的延迟。当然,基础设施无法知道问题的暂时性

第二个原因是,如果它们都相同,那么配置起来就更容易了。每个级别的X次重试和Y次尝试次数=X*Y次总尝试次数,配置文件中只有2个数字。在NServiceBus中,这两个值加上后退时间跨度,因此配置如下所示:

<SecondLevelRetriesConfigEnabled="true" TimeIncrease ="00:00:10" NumberOfRetries="3" />
<TransportConfig MaxRetries="3" />

这相当简单。试3次。等10秒钟。试3次。等20秒。试3次。等30秒。试3次。完成后,您将进入一个错误队列


为每个级别配置不同的值需要更复杂的配置故事。

+1原因有多种。我选择这个作为“正确答案”,而不是Fyles的答案,因为这更彻底。好答案,值得接受正确答案,但我只想给出另一个例子,为什么自动重试是件好事。消息传递是异步的。您不能合理地期望消息以特定的顺序到达。重试使您能够编写并不意味着排序的代码。如果“第二条”消息首先到达,则抛出异常,然后重试。在这几毫秒内,“第一条”消息可能已经到达并被处理。因此,重试有助于补偿消息传递的异步性质。