关于一个 websocket 多节点分布式问题的头条面试题

原文连接,欢迎讨论: 【Q023】websocket 服务多节点部署时会有什么问题,怎么解决 git

你来讲说 websocket 有什么用github

双向通讯,服务器端能够主动 push,给客户端发送通知web

那websocket多个节点有什么问题?面试

头条面试官的提问让个人回忆飘到了一个下午,想起了我两个同事之间的对话redis

引子

咱有部分用户收不到通知了服务器

通知是由ws服务控制的,它最近是有啥改动么websocket

也没改啥,之前单个节点也没有问题负载均衡

想起来了,接上面通知,把服务都从单节点改为了多节点socket

对,说是为了什么 HA,两位数用户的服务须要折腾吗分布式

没事,这样出去了也有搭建高可用服务与 websocket 负载均衡的经验了

说的倒也是!不过这样确实会有 ws 分布式的问题

简单,加个 reids 就行了

多节点问题

在开始思考分布式会有什么问题时,先来回答一个问题: 服务端如何与客户端交流?

在 ws 服务端,当与客户端链接成功后,会生成一个对象 connection,ws 会维护一个与客户端全部链接的 connections。若是想要主动推送消息到客户端,只须要调用API connection.sendText(message)

那如何给全部人广播消息呢?

服务器只须要与它自身的全部链接 server.connections 挨个发消息就是广播,因此它只是一个伪广播:我要给群里全部人发消息,但我不能在群里发,只能挨个私发。

单节点

当单节点时全部用户都能正常受到通知,流程以下

ws 单节点时

这时全部用户都能收到消息通知

多节点

当多节点时,就会有部分用户没法正常受到通知,从如下流程图中能够很清楚地看到问题所在

ws 多节点时

负载到节点2的全部用户都没有收到消息通知

如何解决

多节点服务器就会有分布式问题,解决分布式问题就找一个你们都能找到的地,好比说 Redis,好比说 Kafka 等消息件

改进后流程图以下

  1. 须要向全部用户推送消息,请求 websocket 服务
  2. 负载均衡到某个节点
  3. 该节点向 redis/kafka 推送消息: 向全部用户推送消息通知
  4. 全部节点在 redis/kafka 上订阅消息
  5. 订阅成功后全部节点向客户端 push 消息

借用 redis

redis PUBSUB

其中有一个细节是 pub/sub 那里,redis 的 pubsubKafka 等消息中间件更为轻便,最主要的是与ws集成的社区方案比较成熟,这点很重要,如 Node 中的如下两个

pubsub 在 redis 中的命令以下

  • pub: publish channel message
  • sub: subscribe

若是咱们要订阅 eat 这个 channel 的话,图示以下

redis pubsub example

小结

借用解决方案的图做为小结

借用 redis

相关文章
相关标签/搜索