WebSocket(ws)集群解决方案

1,307 阅读2分钟

1:前言

在某种特定的场景中,需要实现服务器主动向客户端推送数据的目的,这时候ws就出来了。如下模型

image-20201223143551028

但是这种的存在这单点问题,那么如何解决这种单点问题,很简单,我们直接通过nginx来配置集群就可以了,如下(nginx 是支持ws集群的)

image-20201223142538167

配置如下

 map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
  }

image-20201223143138743

2:问题

现在项目已经部署好了,会不会有什么问题呢?接下里我们分析下

由于负载均衡的原因,可能会出现如下情况

client1通过http请求服务器A,然后需要服务器通过ws推送数据给client2,但是这个时候,client2连接的是另外一台服务器B,由于服务器A和client2之间没有保持ws,所以数据是无法通过服务器A推送给client2的,还是要通过服务器B把数据推送过去,我们此时就需要一个连接的桥梁,让服务器B知道自己要推送数据给client2

image-20201223144312801

3:解决思路

3.1:jvm之间的通信问题

通过什么样的方式可以做到通知,http?tcp?或者是一些消息队列之类的东西

3.2:通信的数据格式的约定

在jvm之前要数据传输,jvm2上接收到jvm1中的数据的时候,应该去约定一个数据格式(协议),该怎么去解析,怎么去发送,发送的消息指定机器名称,给每一个jvm匹配一个消息队列

{"to":"serverB",
 "data": "你好呀~"
}
3.3:client2连接在哪一台服务器上

可以通过client2在连接服务器的时候向redis中去搞一个注册表,<client2, jvmName>

3.4:client2是否在我http请求的机器上

可以通过client2在连服务器的时候在当前jvm缓存中添加一个键值对<client2, wsclient>

3.5:整体流程图

image-20201223175357652

4:总结

如果在某一个维度解决不了问题,我们是不是可以升一个维度去思考,一般来说都是可以的,很多的问题都是这么解决,例如经典的分布式锁,是通过升维去解决的。

\