我有一个有趣的难题;我使用redis pubsub模式在nodejs微服务网络中发出事件。我离开了rabbitmq,因为我需要多播消息,以便多个微服务可以接收和处理同一事件。因此,如果我发出一个注销事件,userservice和websocketservice都应该听到它。
在我的客户机部署到每个微服务都有多个示例运行的环境中之前,这一切都很正常。现在,给定3个userservice示例,所有示例都连接到redis,它们都接收并处理logout事件,这很糟糕。
因此,一方面我需要不同的微服务来收听事件,但另一方面我需要防止同一微服务的重复副本处理所有事件。岩石,遇到坚硬的地方。
到目前为止,我最好的想法是有点老套,但有点像:
不要引发事件,而是向redis缓存写入事件列表
userservice和websocketservice可以每3秒读取一次该列表,并检查需要处理的新事件
当找到相关事件时,userservice会将其“名称”添加到处理该事件的服务列表中
当websocketservice看到该事件时,它仍然能够处理该事件并将其“名称”添加到处理程序列表中
当重复的userservice示例看到该事件时,它将在处理程序列表中看到其“名称”,并忽略该事件
我不喜欢这个解决方案,因为列表将在内存中不断增长,而不是在一个短暂的消息中。我还必须开始添加代码来管理哪些事件已经被检查过;否则,每个周期,整个列表都必须由所有服务的所有示例再次解析。
欢迎提出意见。
4条答案
按热度按时间yh2wf1be1#
redis流似乎对您的用例很有帮助。你查过了吗?。
我们可以有多个消费者群体。与pub/sub一样,每个消费者组都需要从流中接收消息(这里的流类似于pub/sub-channel/topic)。但是,当使用者组中有多个节点时,只有一个节点将处理事件。不是全部。节点可以确认它已处理的消息。
重新启动后,节点将不会处理已传递的消息
溪流将继续增长。我们可以根据大小修剪。我们可以保留最新的n个元素。
owfi6suc2#
收到通知后,使用lpop使用redis上的事件列表,并且仅当列表中确实有某些内容时才执行操作。
这既可以清理事件列表,又可以保证只有一个使用者实际执行一个操作。
ybzsozfc3#
对于您描述的场景,我将同时使用两种模式:一种是使用redlock实现的事件队列(或者更具体地说是针对每个使用者集群的事件队列),另一种是pubsub模式,用于提醒所有使用者新事件已准备好被消费。对于您建议的解决方案,这应该是一个更被动的解决方案,因为没有轮询,但是对队列的访问是事件驱动的。
wqnecbli4#
嘿,在多个示例上运行服务器之后,我遇到了同样的问题。
在我的例子中,我使用mongodb作为数据库,所以每当我收到一个keyspace通知时,我就为这个特定的订阅创建一个db写锁。
所以我自己创建了一个写锁,每当我得到你订阅的那个密钥的订阅时,我就把这个文档的密钥增加1。通过更新我得到nmodified:1 in 我的案子一旦通过创造一些相应的条件进行了修改。
因此,一旦服务器通过创建一些条件发送多个请求,我就设法输入该条件并更新该密钥,然后执行我想要的任何任务。
您也可以通过创建自己的写锁来实现这一点。
冰雹编码