關於一個 websocket 多節點分佈式問題的頭條前端面試題

原文連接,歡迎討論: 【Q023】websocket 服務多節點部署時會有什麼問題,怎麼解決 前端

你來講說 websocket 有什麼用?git

雙向通訊,服務器端能夠主動 push,給客戶端發送通知。我想着,這仍是較爲簡單的程序員

那websocket多個節點有什麼問題?github

頭條面試官的提問讓個人回憶飄到了一個下午,想起了我兩個同事之間的對話web

引子

咱有部分用戶收不到通知了面試

通知是由ws服務控制的,它最近是有啥改動麼redis

也沒改啥,之前單個節點也沒有問題前端工程化

想起來了,接上面通知,把服務都從單節點改爲了多節點服務器

對,說是爲了什麼 HA,兩位數用戶的服務須要折騰嗎websocket

沒事,這樣出去了也有搭建高可用服務與 websocket 負載均衡的經驗了

說的倒也是!不過這樣確實會有 ws 分佈式的問題

簡單,加個 reids 就行了

多節點問題

在開始思考分佈式會有什麼問題時,先來回答一個問題: 服務端如何與客戶端主動PUSH?

在 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

進一步追問

面試官見我回答完問題後,又一次追問

那 websocket 如何向特定的用戶組推送消息?

假如一個學校有如下數據結構

  1. Class: 表明班級
  2. Student: 表明學生,每一個學生都在其中一個班級

那假如要向 Class:201901 班級的全部學生髮送通知,應該如何實現

歡迎在 Issue 中討論: 【Q029】websocket 如何向特定用戶組推送消息

小結

借用解決方案的圖做爲小結

借用 redis

最後,面試結束,頭條的面試官很滿意,問,你有什麼問題要問我嗎

我問道,那能夠點個贊嗎


我是山月,一個喜歡跑步與登山的程序員,我會按期分享全棧文章在我的公衆號中。若是你對全棧面試,前端工程化,graphql,devops,我的服務器運維以及微服務感興趣的話,能夠關注我

若是你對全棧面試,前端工程化,graphql,devops,我的服務器運維以及微服務感興趣的話,能夠關注我
相關文章
相關標籤/搜索