本文由微信技術團隊分享,原題“十年前的微信消息收發架構長啥樣?”,下文進行了排版和內容優化等。
1、引言
2023 年,微信及 WeChat 的 DAU(月活用戶)達到 13.4 億,微信已經是很多人工作、生活中不可或缺的一個環節。從 2011 年 1 月 21 日上線至今,微信已經走過了 13 個年頭,其背后的技術基座與架構也發生了巨大的變化。這些變化背后,所折射的也正是中國互聯網高速發展的黃金年代。
好的架構是迭代出來的,卻也少不了良好的設計,本文將帶大家回顧微信背后最初的也是最核心的IM消息收發技術架構,愿各位讀者能從中獲得啟發。

技術交流:
- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點此)
(本文已同步發布于:http://www.52im.net/thread-4636-1-1.html)
2、微信技術起步
微信誕生于 QQMail 團隊,初始的整個微信后臺架構都帶著濃重的郵箱氣息,消息收發架構作為微信最為核心的部分,同樣是基于郵箱的存儲轉發機制演變而來。
微信定位為即時通訊IM軟件,對消息的收發有2個基本的要求:
- 1)消息盡可能的實時送達;
- 2)不丟消息。
在郵箱的存儲轉發機制上做了改良后,微信的消息收發實現了以上2個基本要求。
3、消息發送架構
首先通過手機 A 給手機 B 發送一條微信消息來看消息發送的整體架構是怎樣的(如下圖所示)。
微信消息發送在整體架構上可以分為2個部分。
第一部分:手機A發送消息到服務器(上圖中1、2、3部分):
- 1)1 - 手機A發送發消息請求到接入層 ConnnectSvr;
- 2)2 - 接入層收到請求后,將請求轉到邏輯層 SendSvr 進行處理;
- 3)3 - 邏輯層處理完各種邏輯(如反垃圾,黑名單等等)之后,將消息存入存儲層 MsgStore。
第二部分:服務器發送通知到手機B(上圖中4、5.1、5.2、6、7部分):
1)4 - 邏輯層 SendSvr 將給手機 B 的新消息到達通知發送到通知處理服務器 PushSvr。
2)5.1 - PushSvr 查詢手機 B 在接入層所在長連接的 ConnectSvr,并將通知發給該 ConnectSvr。
3)5.2 - PushSvr 發送一個 Push tips 給手機操作系統自建的第三方 Push 系統(如蘋果的 APNsPush,微軟的 WPPush,黑莓的 BBPush 等)。像蘋果的 IOS 系統,在 APP 退出到后臺10分鐘后就會釋放掉該 APP 所持有的所有資源(如 CPU,網絡,內存等),導致之前建立的長連接通道也會一并斷掉,此時通過5.1的方式進行通知是不可達的,所以還需要依賴與蘋果自身的 apns 通道來達到實時通知的目的。
4)6 - 接入層 ConnnectSvr 通過手機 B 建立的長連接通道將新消息達到通知發送給手機 B。
5)7 - 第三方 Push 服務器通過自建的 Push 通過發送 Push tips 到手機 B。
4、消息接收架構
手機 B 在收到新消息到達通知后進行消息收取的整體架構如下圖所示:

消息收取的流程主要分為3個步驟:
- 1)手機 B 發起收取消息的請求到接入層服務器 ConnnectSvr;
- 2)接入層服務器 ConnnectSvr 接到請求后轉給邏輯層服務器 ReceiveSvr 進行處理;
- 3)ReceiveSvr 從存儲層 MsgStore 中獲取到需要下發的消息。
5、消息收發架構小結
在上述第4、5兩節中分享的消息收發架構保障之下,微信可以保證手機 A 在發出消息 100ms 級別內讓手機 B 收取到該條消息。
當然,對于退出后臺的蘋果 iOS 的微信用戶,在蘋果的 APNs 服務器正常的情況下,也可以保證在秒級別內通知到手機 B 點開 APP 進入前臺來收取消息。
6、消息防丟失機制
雖然消息收發架構保證了消息收發雙方能夠及時收發消息,但該架構不能保證消息在傳輸過程中不發生丟棄。
當然為了達到任意一條消息都不丟的狀態,最簡單的方案是手機端對收到的每條消息都給服務器進行一次 ack 確認,但該方案在手機端和服務器之間的交互過多,并且也會遇到在弱網絡情況下 ack 丟失等問題。
為了完美的做到消息不丟,微信消息系統對消息收發引入了 sequence 機制。
PS:感興趣的話,以下是更多與IM消息送達保證有關的文章,可以一并閱讀:
- 理解IM消息“可靠性”和“一致性”問題,以及解決方案探討
- 融云技術分享:全面揭秘億級IM消息的可靠投遞機制
- 從客戶端的角度來談談移動端IM的消息可靠性和送達機制
- IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞
7、消息防丟失機制技術實現
7.1sequence 機制
- 1)每個用戶都有42億的 sequence 空間(從1到 UINT_MAX),從小到大連續分配;
- 2)每個用戶的每條消息都需要分配一個 sequence;
- 3)服務器存儲有每個用戶已經分配到的最大 sequence;
- 4)手機端存儲有已收取消息的最大 sequence。
PS:微信sequence序列號生成的具體算法和實現詳見《微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)》。
7.2消息收取sequnece確認機制
當服務器和手機端都擁有了一個 sequence 之后,服務器和手機端之間就可以根據兩者 sequence 的差異來收取消息,同時保證手機端未收取下去的消息最終能夠收取下去。
具體流程如下圖表示:

1)根據服務器和手機端之間 sequence 的差異,可以很輕松的實現增量下發手機端未收取下去的消息。
2)對于在弱網絡環境差的情況,丟包情況發生概率是比較高的,此時經常會出現服務器的回包不能到達手機端的現象。由于手機端只會在確切的收取到消息后才會更新本地的 sequence,所以即使服務器的回包丟了,手機端等待超時后重新拿舊的 sequence 上服務器收取消息,同樣是可以正確的收取未下發的消息。
3)由于手機端存儲的 sequence 是確認收到消息的最大 sequence,所以對于手機端每次到服務器來收取消息也可以認為是對上一次收取消息的確認。一個帳號在多個手機端輪流登錄的情況下,只要服務器存儲手機端已確認的 sequence,那就可以簡單的實現已確認下發的消息不會重復下發,不同手機端之間輪流登錄不會收到其他手機端已經收取到的消息。
如上圖4所示:假如手機 A 拿 Seq_cli = 100 上服務器收取消息,此時服務器的 Seq_svr = 150,那手機 A 可以將 sequence 為[101 - 150]的消息收取下去,同時手機 A 會將本地的 Seq_cli 置為150。

如上圖5所示:手機 A 在下一次再次上來服務器收取消息,此時 Seq_cli = 150,服務器的 Seq_svr = 200,那手機 A 可以將 sequence為[151 - 200]的消息收取下去。
如上圖6所示:假如原手機 A 用戶換到手機 B 登錄,并使用 Seq_cli = 120 上服務器收取消息,由于服務器已經確認 sequence <= 150 的消息已經被手機收取下去了,故不會再返回 sequence 為[121 - 150]的消息給手機 B,而是將 sequence 為[151 - 200]的消息下發給手機 B。
這里雖然 sequence 為[151 - 200]的消息有可能是被手機 A 和手機 B 都收取到,但由于手機 A 在收到 sequence 為[151 - 200]的消息時并沒有給服務器進行確認或者這些消息手機 A 壓根就沒有收取到,所以為了防止消息丟失,sequence 為[的消息也是需要下發給手機 B 的。
8、本文小結
以上簡單文字描述的就是微信最初的IM消息收發的架構。
該架構實現了即時通訊軟件對消息收發所需的兩個基本要求:
- 1)消息盡可能的實時送達 ;
- 2)不丟消息。
以上:是 2014 年微信古早時期的消息收發架構的基本介紹,時過境遷,微信的消息收發架構已經發生了巨大的變化,但我們還是可以從中看到技術演變的價值與力量。
程序員最大的成就與幸福,或許就是自己的代碼跑在千萬人的設備上,默默支撐著海量的需求。
9、參考資料
[1] iOS的推送服務APNs詳解:設計思路、技術原理及缺陷等
[2] 了解iOS消息推送一文就夠:史上最全iOS Push技術詳解
[3] 消息推送技術干貨:美團實時消息推送服務的技術演進之路
[4] 微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)
[5] 企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等
[6] 一套億級用戶的IM架構技術干貨(上篇):整體架構、服務拆分等
[7] 一套億級用戶的IM架構技術干貨(下篇):可靠性、有序性、弱網優化等
[8] 從新手到專家:如何設計一套億級消息量的分布式IM系統
[10] 從客戶端的角度來談談移動端IM的消息可靠性和送達機制
[11] IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞
[12] IM開發寶典:史上最全,微信各種功能參數和邏輯規則資料匯總
[14] 理解IM消息“可靠性”和“一致性”問題,以及解決方案探討
10、微信團隊的其它文章
《前創始團隊成員分享:盤點微信的前世今生——微信成功的必然和偶然》
《即時通訊創業必讀:解密微信的產品定位、創新思維、設計法則等》
《[技術腦洞] 如果把14億中國人拉到一個微信群里技術上能實現嗎?》
《讀懂微信:從1.0到7.0版本,一個主流IM社交工具的進化史》
《還原真實的騰訊:從最不被看好,到即時通訊巨頭的草根創業史》
《專訪馬化騰:首次開談個人經歷、管理心得、技術創新、微信的誕生等》
《一文讀懂微信之父張小龍:失敗天才、顛覆者、獨裁者、人性操控師》
《微信團隊分享:極致優化,iOS版微信編譯速度3倍提升的實踐總結》
《IM“掃一掃”功能很好做?看看微信“掃一掃識物”的完整技術實現》
《微信團隊分享:微信支付代碼重構帶來的移動端軟件架構上的思考》
《IM開發寶典:史上最全,微信各種功能參數和邏輯規則資料匯總》
《微信團隊分享:微信直播聊天室單房間1500萬在線的消息架構演進之路》
《企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等》
《IM全文檢索技術專題(四):微信iOS端的最新全文檢索技術優化實踐》
《微信團隊分享:微信后臺在海量并發請求下是如何做到不崩潰的》
《微信Windows端IM消息數據庫的優化實踐:查詢慢、體積大、文件損壞等》
《IM跨平臺技術學習(九):全面解密新QQ桌面版的Electron內存優化實踐》
《揭秘企業微信是如何支持超大規模IM組織架構的——技術解讀四維關系鏈》
《微信團隊分享:詳解iOS版微信視頻號直播中因幀率異常導致的功耗問題》
《微信團隊分享:微信后端海量數據查詢從1000ms降到100ms的技術實踐》
《大型IM工程重構實踐:企業微信Android端的重構之路》
(本文已同步發布于:http://www.52im.net/thread-4636-1-1.html)
作者:Jack Jiang (點擊作者姓名進入Github)
出處:http://www.52im.net/space-uid-1.html
交流:歡迎加入即時通訊開發交流群 215891622
討論:http://www.52im.net/
Jack Jiang同時是【原創Java
Swing外觀工程BeautyEye】和【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
本博文
歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。