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

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

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

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

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