有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

语言:springboot,JS

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

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


共 (1) 个答案

  1. # 1 楼答案

    为了解决这个问题,可以观察以下方法

    DNS概念

    如果你仔细想想,知道你的用户(SSE发射器)在哪里,就像知道某个网站在哪里一样。您可以使用DNS相似协议来确定用户所在的位置。议定书如下:

    • 当用户登录到任何实例时,将用户与该实例关联。关联可以通过使用外部组件(如Redis)或分布式地图解决方案(如Hazelcast)来完成
    • 每当用户从SSE断开连接时,删除关联。有时,disconnect未正确注册到Spring SSEEmiter,因此当sendig消息失败时,可以进行解除关联
    • 其他方(微服务)可以轻松地查询Redis/Hazelcast,以确定用户是哪个实例

    消息路由概念

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

    • 每个SSE实例在引导时创建自己的队列
    • 用户登录到任何SSE实例上,该实例使用路由键=用户uid添加exchange队列绑定
    • 每当用户从SSE断开连接时,删除关联。有时,disconnect未正确注册到Spring SSEEmiter,因此当sendig消息失败时,可以进行解除关联
    • 其他方(微服务)需要向exchange发送消息并定义路由密钥。AMQP代理根据路由密钥确定应该接收消息的队列

    在现代AMQP代理(如RabbitMQ)上,绑定不是无资源干扰的

    你的问题很老了,如果你现在还没有弄明白,希望这能有所帮助