后端缩放时如何有效地发布到 graphql 订阅者

How to publish effectively to graphql subscribers when backend scaled

我有后端副本以提供水平扩展。后端有 apollo graphql 订阅。还有一个微服务为特定订阅提供通知。

由于我不在后端保留任何状态,因此我尝试通过实施 Redis PUB/SUB 来解决问题。当微服务接收到事件时,它会发布到后端。

在后端的订阅解析器中我有

webhookCalled: {
    subscribe: withFilter(
            () => pubsubMyEvent.asyncIterator([MY_EVENT]),
            (payload, _, context) => {
                return context.dataValues.id == payload.userid;
            }
        )
    }

在上面的代码中,我试图过滤掉负载未发送到的订阅。我不太确定 withFilter 例程的成本是多少。 当我收到来自 Redis 的 PUB 时,我正在调用

pubsubMyEvent.publish(MY_EVENT, { myEventData });

这里我不喜欢的是每个后端都将处理(publish(...))所有事件,即使最后只有一个后端实际将订阅消息发送到 graphql 客户端。

问题:如何有效地处理向 graphql 订阅客户端发送事件,同时具有可扩展的后端?当需要通知单个 websocket 连接时,也许不要打扰所有后端副本。我是否应该跟踪 Redis 中所有连接的客户端,以便 Redis 知道每个 graphql 订阅客户端的连接位置?

将发布的事件发送给所有订阅同一个频道的客户端,这是redis的特性。

一种保持相同架构的可能解决方案是为每个用户使用不同的频道,而不是只使用一个频道。支持者应在新用户连接后订阅频道 MY_EVENT + user.uuid,并在用户断开连接后取消订阅同一频道。另一方面,一旦调用 webhook,该服务不应在全局通道上发布,而应在 MY_EVENT + user.uuid 通道上发布。