我们有超过 100 个微服务使用来自 Rabbitmq 的消息,但是由于网络问题,服务和 Rabbitmq 之间的连接丢失并恢复(重新建立),然后消息重新传递,服务再次处理这些消息,这对我们来说可能是致命的.
我读到了“RabbitMQ 消息重复数据删除插件”,但其设计目的是防止发布者发布重复消息。 以最低成本处理这种情况的建议做法是什么?
一般来说,不可能保证消息只会被处理一次(在网络或计算故障可能性非零的系统中,没有任何消息传递基础设施可以做出这种一般保证):您可以保证最多一次(不重新投递)或至少一次(重新投递)。
可以(至少在许多应用程序中)通过将至少一次传递(重新传递消息直到确认已成功处理)与幂等处理相结合,以“有效一次”的方式处理消息:处理相同的消息n> 1 次与仅处理一次具有相同的可观察效果(一般来说,当消息传递基础设施声明恰好一次时,它们的意思是“有效一次”)。从某种意义上说,这正在改变服务处理消息的方式,使其不会致命。
如何(或者是否)实现这一点取决于处理:一般要求是您的服务必须能够保留足够的自身状态来记录它已经处理了给定的消息,并且能够记录该消息与处理一起原子处理(以便消息被处理并记录为已处理,或者既没有被处理也没有被记录为已处理:如果消息有可能被记录为已处理但未处理,那么您已经付出了努力最多重新实现一次,反之亦然至少重新实现一次)。例如,如果处理仅需要更新关系数据库,您可以记录该消息是在与实际处理更新相同的数据库事务中处理的。