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

时间:2018-12-18 08:32:16

标签: java spring-boot microservices spring-cloud server-sent-events

语言:Spring Boot,JS

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

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

1 个答案:

答案 0 :(得分:0)

要解决此问题,可以采用以下方法。

DNS概念

如果您考虑一下,那么知道用户(SSE发射器)在哪里,就像知道某个网站在哪里。您可以使用类似DNS的协议确定用户的位置。协议如下:

  • 用户登陆到您的任何实例上时,请将用户与该实例相关联。关联可以通过使用外部组件(例如Redis或像Hazelcast这样的分布式地图解决方案。
  • 每当用户与SSE断开连接时,请删除关联。有时,断开连接未在Spring SSEEmiter中正确注册,因此当sendig消息失败时可以解除关联。
  • 其他方(微服务)可以轻松查询Redis / Hazelcast来确定实例用户的身份。

消息路由概念

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

  • 每个SSE实例在启动时创建他们自己的队列
  • 用户登陆到任何SSE实例上,并且实例通过路由键=用户uid添加了交换队列绑定
  • 每当用户与SSE断开连接时,请删除关联。有时,断开连接未在Spring SSEEmiter中正确注册,因此当sendig消息失败时可以解除关联。
  • 其他各方​​(微服务)需要向交换机发送消息并定义路由密钥。 AMQP代理根据路由密钥确定哪个队列应该接收消息。

在像RabbitMQ这样的现代AMQP经纪人上,绑定不是资源固有的。

您的问题很旧,如果您现在还没有解决这个问题,希望对您有所帮助。