天天看點

【微服務】微信的消息收發機制

微信可能是國内最早一批做微服務架構體系的,畢竟微服務的理念與騰訊一直倡導的“大系統小做”有很多相通之處,當然微信的功能有很多,衣食住行都能找到入口。我們今天單說它的原生功能:即時通信。

    這塊内容本座想分兩部分來講,第一部分是點到點聊天,第二部分是群組聊天。這兩種聊天模式有共同點,比如說已讀資訊不會在服務端保留,是以換新手機是找不到曆史消息的。也有不同點,比如服務端的架構和資料流等等。

    先說點到點聊天,手機端通過打開微信軟體建立了到騰訊雲的微信網關,當然考慮到就近通路與負載平衡,不同用戶端可能連到不同的網關。當A使用者通過網關B發送微信給線上使用者B時,會話微服務會記錄目前所有使用者的連入資訊,維護如下的使用者-網關表:           
使用者 網關
A B
C

如果對端使用者不線上,則會記錄上次連接配接的網關,如果從來沒線上過則随機配置設定網關。這張表雖然有高達10億的記錄(微信使用者數量),但好在隻是一張二維表而且可做冷熱分離,是以存儲量并不大,然後各個網關上會有熱資料的分布式緩存。

為什麼要這樣做呢,因為我們知道讓一台網關伺服器來維持每一個用戶端的TCP連接配接是非常消耗記憶體的,鑒于微信使用者的數量,一般硬體的性能是無法達到的,是以通過會話微服務來記錄這些資訊可以很好地為網關減負。

【微服務】微信的消息收發機制

接下來當消息進入到會話微服務找到B對應的網關,然後通過該網關将消息傳遞給B使用者。

等等,什麼,網關在沒有使用者請求的情況下還能直接給使用者發消息,這是我認識的CS架構麼?當然通過長輪詢(Long Polling)可以定期從服務端拉資料,但這就影響了消息的實時性了。傳統的HTTP看似無法實作了,我們想到的辦法是WebSocket(WSS)。WSS是通過單個TCP連接配接提供全雙工(雙向通信)通信信道的計算機通信協定。它允許使用者和伺服器之間的流連接配接,并允許即時資訊交換。

Ok,消息傳遞到線上使用者B了,B使用者回複給伺服器“已收到”的回執(不論已讀還是未讀),會話伺服器再以WSS形式将回執轉發給A。當然如果B使用者離線,消息會存放在消息資料庫中直到過期(三天?)。是以點對點聊天在伺服器上并不消耗太多的存儲資源。

接下去我們說說群組消息,當會話微服務識别到消息的接收方是一個群組時,會去調用群組微服務,群組微服務的表結構是一張一對多的分布式資料表:

群組ID
XXX
YYY
D
E

得到目标群的使用者清單後,會話微服務再查詢自己的會話資料庫找到使用者對應的網關,通過WebSocket的形式發送給該群組的所有成員。

【微服務】微信的消息收發機制

當然就像新浪在李晨發“我們”,鹿晗發“官宣”,中國國家男子足球隊發“對不起”的時候會發生伺服器當機現象,新浪的處理方式是将粉絲群切片,分批次發給不同子群。微信也會在成員過多的群通過異步的消息隊列進行批量多點傳播,但即便如此,與點到點微信不同的是,網關的負擔會大很多,是以除了将會話微服務從網關上拆解,還需要進一步将驗證服務、語義分析服務(各種網絡協定的解包)從網關伺服器上拆解下來,由此就形成了微信的群族消息的資料流。