防止 NodeJS 处理 Redis PubSub 事件的多个实例

Bee*_*ice 5 publish-subscribe redis node.js

我有一个有趣的难题;我使用 Redis PubSub 模式在 NodeJS 微服务网络中发出事件。我放弃了 RabbitMQ,因为我需要多播消息,以便多个微服务可以接收和处理同一事件。因此,如果我发出 LOGOUT 事件,UserService 和 WebSocketService 都应该听到它。

在我的客户端部署在每个微服务的多个实例运行的环境中之前,这种方法工作得很好。现在,给定 UserService 的 3 个实例,所有实例都连接到 Redis,并且它们都接收并处理 LOGOUT 事件,这很糟糕。

因此,一方面,我需要不同的微服务来监听事件,但另一方面,我需要防止同一微服务的重复副本全部处理该事件。摇滚,遇到困难的地方。

到目前为止,我最好的想法有点老套,但类似于:

  1. 不引发事件,而是将事件列表写入 Redis 缓存
  2. UserService 和 WebSocketService 可以每 3 秒读取一次该列表并检查是否有需要处理的新事件
  3. 当发现相关事件时,UserService 会将其“名称”添加到正在处理该事件的服务列表中
  4. 当 WebSocketService 看到该事件时,它仍然能够处理该事件并将其“名称”添加到处理程序列表中
  5. 当 UserService 的重复实例看到该事件时,它将看到其“名称”已在处理程序列表中,并忽略该事件

我不喜欢这个解决方案,因为该列表将在内存中而不是在瞬态消息中不断增长。此外,我还必须开始添加代码来管理已检查的事件;否则,每个周期,所有服务的所有实例都必须再次解析整个列表。

欢迎提出想法。

vin*_*ins 5

Redis 流似乎对您的用例有帮助。你检查了吗?

我们可以有多个消费者群体。与 pub/sub 一样,每个消费者组都希望从流中接收消息。(这里的流就像发布/订阅频道/主题)。然而,当一个消费者组内有多个节点时,只有一个节点会处理该事件。不是全部。节点可以确认它已处理的消息。

  • 重启后,节点将不会处理已经发送的消息
  • 流将继续增长。我们可以根据尺寸进行修剪。我们可以保留最新的N个元素。

在此输入图像描述


Dan*_*ore 0

收到通知后,使用LPOP消耗 Redis 上的事件列表,并且仅在该列表上确实存在某些内容时才采取行动。

这将清理事件列表并保证只有一个消费者会实际执行一项操作。