我正在寻找一种设计我的系统的方法,该系统由多个发布者,多个频道和多个订阅者组成,所有这些都可以轻松识别。 我需要在两个方向上发送消息,并尽可能降低延迟。但是,如果订阅者死亡,他订阅的消息不应该被删除,当它重新联机时,它应该接收所有未决消息。由于我处理的消息数量非常多(定期发生每秒高达1000次),而具有低规格的服务器,这意味着无法始终保留所有消息的列表。
我在考虑邮件的引用计数/列表是否可行。发布消息时,将使用该特定通道的订户列表对其进行初始化,当订户收到消息时,将从列表中删除订户。如果列表为空,则删除该消息。
现在,如果订阅者在没有取消订阅的情况下死亡,则不会删除消息,因为缺少的订阅者列表不为空。当它重新联机时,它将能够接收所有未决消息的列表,因为它使用与死实例相同的ID进行标识。
可能需要让消息/订阅者超时,例如,如果订阅者已处于非活动状态10分钟,则包含该消息/订阅者的所有列表条目都将被清除。
这是一个好主意,我是否忘记了特别是这个系统可能出现的问题?有没有系统已经这样做了? RabbitMQ和类似的PubSub系统似乎没有这个 - 如果没有,我想redis是要走的路?
答案 0 :(得分:2)
我可以想象为了消息生命周期而管理引用计数。在正常的服务操作期间,这在消息和内存管理方面听起来很合理。当然,超时为死服务的引用提供补丁。
然而,在健康监测和服务恢复问题方面,这是另一个故事。
我目前看到的危险是国家管理。想象一下,作为有状态订户(即具有状态机)的服务从其初始状态(I)驱动到某个状态(S)。每条消息在不同状态下的处理方式不同。现在假设你的服务死了并重新启动。同时存储一些消息,并且在服务重新联机后,它们被分派给它。然而,服务在错误的状态(我而不是S)接收它们并且意外地行动。
您能否以崩溃时的确切状态恢复服务?实际上,这非常困难,因为即使在State Machine方法中,服务也会产生副作用/与全球状态等进行通信。
底线,引用计数在管理消息方面似乎是合理的,但将其与健康监控混合会导致许多复杂性问题。