一、前言
- 不知不覺來到新公司已經快半年,經歷了智能客服項目從剛開線時什麼都不確定,到現在系統基本穩定並且扛過了大促時的高峯流量,這其中經歷了很多艱辛,但是也的確收穫了很多。特別是剛開始從原有阿里雲客服流量全切我們系統時,很多問題都爆發了出來,由於是我負責核心通信模塊的開發,自然也是由我去跟蹤線上問題並解決。也是跳過了很多坑,在這裏總結一下吧
二、原有的通信架構
- 在我沒來之前,其實項目已經啓動了一段時間了,但是只是在開發相應的基礎模塊,所以通信這塊只是實現了簡單的首發消息,採用了Netty框架,通信協議採用的websocket
- 技術實現:
- websocket+Netty+mq
- 交互步驟:
- 首先前端頁面通過http請求攜帶用戶token請求服務端
- 服務端驗證token,驗證成功後將用戶信息和channel緩存在本地,並將請求升級爲websocket協議,此時建立連接
- 當服務端接收到用戶發送的消息時,直接將消息丟到MQ進行羣發
- 每個Netty節點同時作爲一個MQ消費者,消費該消息,根據消息體中指定的消息目的地尋找本地是否有對應的channel,如果沒有丟棄消息,如果有的話進行發送
- 簡易架構圖
- 缺點:
- 效率很低,不適合高併發的場景下
- 無法確保消息的可達性,出現丟消息的情況
三、通信架構改進
- 由於要迎接後續的分段切流量,現在的通訊方式肯定不能滿足需求,需要進行改進。當時也是諮詢了架構組,架構組給出的方案就是做Netty節點間的消息投遞
- 方案簡述
- 每當用戶發起HTTP連接併成功升級爲websocket後,後臺會在redis中存儲用戶的路由信息
- 用戶連接到Netty節點A,併發送相應消息
- Netty節點A收到用戶發送的消息,並進行暫存後返回ACK,此時消息發送成功
- Netty節點A根據消息體中消息接收方信息查詢路由,發現消息需要發送到Netty節點B
- 將消息發送到NettyB節點,NettyB節點接收到消息後進行暫存並返回ACK,Netty節點A接收到ACK後刪除暫存的信息
- Netty節點B根據消息體中接收方信息查詢是否存在channel,存在則繼續投遞消息到用戶B
- 用戶B接收到消息後,返回ACK。Netty節點B刪除調用暫存消息
- 此時消息投遞成功
- 簡易架構圖
四、總結
- 這邊總結只是大概簡述了下通信模塊的一個演進過程,其中的消息重推等機制並未詳解。一方面原因的確是忙,爲了實現每週一篇Blog的flag也是不容易。另一方面現在也沒有好好整理這一塊,也是希望自己能夠堅持寫下去,能夠慢慢提高自己的文字水平
- 最後還是自勉一下吧:保持學習