如何在微服务的多个实例之间维护SseEmitters列表?

8

语言:Spring Boot,JS

概述:我正在实现服务器发送事件功能,该功能将部署在Cloud Foundry中。当我订阅了微服务中的某个队列并收到新消息时,我将向正在使用EventSource的客户端/浏览器发送一些更新。为此,在我的服务器端维护一个SseEmitters列表(用于维护所有活动的SseEmitter)。一旦我从队列接收到新消息,根据id(队列消息中的字段),我将向相应的客户端发出消息。

问题:当我通过创建多个实例来扩展应用程序时,上述情况将如何工作。由于只有一个实例会收到新的队列消息,可能会发生在该特定实例中未维护活动的SseEmitter的情况,我该如何解决这个问题?


你能解决这个问题吗? - Maheshkumar
使用Redis缓存或等效工具来存储发射器。 - mtebong
1个回答

0

为了解决这个问题,可以采用以下方法。

DNS概念

如果您考虑一下,知道您的用户(SSE Emitter)在哪里,就像知道某个网站在哪里一样。您可以使用类似DNS的协议来确定您的用户在哪里。协议如下:

  • 当用户登陆到您的任意一个实例时,请将用户与该实例关联起来。关联可以通过使用外部组件,如 Redis 或类似 Hazelcast 的分布式映射解决方案来完成。
  • 每当用户从 SSE 断开连接时,请删除关联。有时 Spring SSEEmiter 无法正确地注册断开连接,因此可以在发送消息失败时执行取消关联。
  • 其他方(微服务)可以轻松查询 Redis/Hazelcast,以确定用户在哪个实例上。

消息路由概念

如果您正在使用消息中间件进行微服务之间的通信,您可以使用 AMQP 协议提供的路由功能。协议如下所示:

  • 每个SSE实例在启动时都会创建自己的队列
  • 用户登陆任何一个SSE实例,实例会添加交换-队列绑定,路由键为用户uid
  • 每当用户从SSE断开连接时,就删除关联。有时候Spring SSEEmiter无法正确注册断开连接,因此当发送消息失败时可以进行取消关联。
  • 其他方(微服务)需要向交换机发送消息并定义路由键。AMQP代理根据路由键确定应该接收消息的队列。

在现代AMQP代理(如RabbitMQ)上,绑定不会占用太多资源。

您的问题很旧,如果您到现在还没有解决它,希望这可以帮助到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接