分布式websocket探索

本文介绍了一个基于Golang的gin框架的Web项目如何采用单体架构并配备WebSocket通讯功能。随着业务发展,面对多实例部署需求,提出了服务拆分及利用消息队列(如NSQ)进行通讯的解决方案,并详细阐述了通过全局Redis存储客户端与服务端关系以及各WebSocket服务器间消息传递的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单体式架构

根据基于golang的gin框架开发的web项目所展开
如果一个Web项目采用单体式架构且配备了websocket通讯的功能,那么在单个实例中是能够正常运行的
在我的项目中,用户可以通过websocket来进行实时通讯和实时消息通知,同时如果在web业务中通过触发条件可以实现实时系统通知
注意:本文的分布式思想不考虑微服务

单台websocket

单台消息互传实现十分简单,通过websocket中转就可以了,不再多加赘述。
在这里插入图片描述

但是随着业务的发展必将同时部署多个实例来分担压力,但此时处于不同实例之间的用户并不能互相通讯

1.服务拆分

一提到服务拆分就会联想到微服务,但是为了这个我们可能要付出重构的代价,凭着合适才是王道的想法,我放弃用微服务重构而是采用服务拆分的思想,以下将不考虑微服务拆分。
我们首先考虑将websocket和web业务进行拆分,用消息队列(以NSQ为例)进行主web业务与websocket业务的下发通讯
在这里插入图片描述

服务拆分后,虽然能够分解一定的压力,但是终究会遇到瓶颈,但是也会面临多实例部署的情况

2.服务拆分后的多实例部署

下列图中 client1和client3/client4 就无法进行通讯
在这里插入图片描述

解决方案

1.使用全局redis存储客户端与服务端的关系,即用户连接到了哪台websocket服务器上;

2.webscoket服务器各自订阅以其他服务器为生产者的消息队列。

发消息流程:

Client与服务器创建连接后会先在本地的map中注册自己的信息,然后在redis中存储Client连接到的服务器编号

情况一:

clientA 给 clientB 发消息时,先从redis中读取clientB在哪个服务器上,如果发现clientA 与clientB 在同一服务器时,会话消息直接在本地上处理发送给clientB

情况二:

clientB 给 clientC 发消息时,从reids中读到clientC和clientB并不在同一服务器上,例如clientC在wsB,那么clientB的消息会被wsA发送到消息队列进行推送,然后消息被推送到wsB,wsB给clientC发送消息。
在这里插入图片描述

我所采用的架构

所有ws实例都会去订阅以所有web实例为生产者的消息队列,以此来实现通过web触发的实时消息推送通知
所有ws实例会互相订阅以ws为生产者的消息队列,实现跨服务器的websocket通讯。

在这里插入图片描述
本文到这里就结束了,欢迎各位小伙伴点赞文章留言讨论,一块儿学习,一块儿进步。

本文思路参考:
分布式websocket解决方案
分布式websocket服务器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值