后端缩放时如何有效地发布到 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
通道上发布。
我有后端副本以提供水平扩展。后端有 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
通道上发布。