spring boot+websocket多节点的解决方案

这里想要聊一聊关于spring boot + websocet的多节点解决方案,当然也只是提供一种思路,并不提供具体的实现代码。

至于websocket是什么,这里我就不多赘述了,所谓多节点,就是在工作中我们可能会遇到,需要部署多个服务,如微服务部署又或者只是单体架构,但是为了提高并发能力,采用ngxin+spring boot部署多个应用,那么如果项目里面使用了websocket,问题也就随之而来了。

javax.websocket.Session是没有办法序列化的,因此没有办法传递给其他应用共享,而假如现在又A、B、C三个websocket节点,通过负载均衡,我们创建websocket连接的时候根据负载均衡的策略是可能连接到A、B、C三个节点之中的任意一个节点。

比如我是用户,我登录了,开始创建websocket节点,此时负载均衡给我分配的是A节点,而后我取通过websocket去发送消息,此时负载均衡给我分配的是B节点,但是B节点上去没有我的连接信息,因此这个消息是无法发送出去的,那么我们应该怎么办呢?

我计划自己封装一个websocket模块(也就是造轮子),用于日后如果用到了websocket技术的话,就可以直接使用了,因此当我基于spring boot实现了websocket的通讯之后,我忽然就意识到了这个多节点的问题,目前我只实现了单节点的通讯,但作为我造的轮子,我自然是不满足于只实现单体架构下的websocket,我还想要实现在多节点或者说微服务下,websocket的通讯,虽然javax.websocket.Session不能序列化,但是我也想要达到一种当我发送消息的时候,当前节点没有我的连接信息,可以平滑的切换到其他的有我的连接信息的应用去,使用我连接过的javax.websocket.Session进行消息的发送。

那么接下来我就说一说我的思路。

也是在我基于RedisTemplate封装Redis模块的时候突然想到了Redis的发布订阅模式,虽然javax.websocket.Session不能序列化,但是我却是可以借助Redis的发布订阅者模式去实现我平滑切换节点去发送消息,因而就可以解决多节点的问题。

大致的解决方案就是,是否是多节点作为一个可配置项,配置在application.yml中,当发送消息时,判断是否开启了多节点,如果不是,就直接在我管理的session池中找到目标的Session然后就是:

String websocketMessageJsonStr = "..."//发送的消息内容
session..getBasicRemote().sendText(websocketMessageJsonStr);

如果不是的话,我不会直接发送消息,而是使用Redis的订阅发布者模式,向指定的通道推送一条消息,这个时候,只需要我所有的开启了多节点模式的websocket应用,监听这个主题,当发送消息的节点推送了这样的一条消息的时候,就去对应的节点找,看有没有对应的消息接收者的Session,如果有则是:

String websocketMessageJsonStr = "..."//发送的消息内容
session..getBasicRemote().sendText(websocketMessageJsonStr);

如果没有的话,则是不做任何的操作,这样就可以确保这条消息一定会被消费。

整体上大致的流程如下:
流程图
其中Redis的部分也是可以用其他中间件代替的,如RebbitMQ等消息队列,总之是可以根据实际情况来去使用这种发布订阅的中间件。

(结语:欢迎大家留言讨论~)

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值