分布式websocket探索

  • Post author:
  • Post category:其他




单体式架构

根据基于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服务器



版权声明:本文为flowerxxxxx原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。