阿里IM技術(shù)分享(三):閑魚億級IM消息系統(tǒng)的架構(gòu)演進(jìn)之路

本文由阿里閑魚技術(shù)團(tuán)隊(duì)今朝、有攸分享,本次有修訂。
1、引言
閑魚即時(shí)消息系統(tǒng)歷經(jīng)數(shù)代迭代,目前已能穩(wěn)定的支撐億級消息體量。
在此消息系統(tǒng)的建設(shè)過程中,我們經(jīng)歷了從簡單到復(fù)雜、從困擾到破局,每一次的技術(shù)改變都是為了更好的解決當(dāng)下業(yè)務(wù)所面臨的問題。
本文分享的是閑魚即時(shí)消息系統(tǒng)架構(gòu)從零開始的技術(shù)變遷之路,以期更多的同行們在此基礎(chǔ)上汲取經(jīng)驗(yàn),得到有價(jià)值的啟發(fā)。

學(xué)習(xí)交流:
- 即時(shí)通訊/推送技術(shù)開發(fā)交流5群:215477170?[推薦]
- 移動(dòng)端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動(dòng)端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK
(本文同步發(fā)布于:http://www.52im.net/thread-3699-1-1.html?)
2、系列文章
本文是系列文章的第3篇,總目錄如下:
《阿里IM技術(shù)分享(一):企業(yè)級IM王者——釘釘在后端架構(gòu)上的過人之處》
《阿里IM技術(shù)分享(二):閑魚IM基于Flutter的移動(dòng)端跨端改造實(shí)踐》
《阿里IM技術(shù)分享(三):閑魚億級IM消息系統(tǒng)的架構(gòu)演進(jìn)之路》(* 本文)
《阿里IM技術(shù)分享(四):閑魚億級IM消息系統(tǒng)的可靠性投遞技術(shù)實(shí)踐》(* 稍后發(fā)布)
3、1.0版:業(yè)務(wù)初創(chuàng)期、最小化可用
3.1 技術(shù)背景
2014年啟動(dòng)閑置交易獨(dú)立APP “閑魚”,一期構(gòu)建完成APP主鏈路,包含商品:發(fā)布→搜索→商品詳情→IM會話→交易。
作為初創(chuàng)APP,業(yè)務(wù)需盡快上線驗(yàn)證效果,技術(shù)建設(shè)上需要完成閑魚消息從無到有的系統(tǒng)搭建。
3.2 技術(shù)方案
作為即時(shí)通訊系統(tǒng),最小化能力包含:
1)消息存儲:會話、摘要、消息;
2)消息同步:推、拉;
3)消息通道:長連接、廠商推送。
與一般IM會話模型不同的是,閑魚會話以商品為主體,“人+人+商品”為要素構(gòu)建會話。
因會話模型的差異,淘系已有的消息系統(tǒng),短期內(nèi)無法滿足業(yè)務(wù)需求,而閑魚完全自建消息系統(tǒng)耗時(shí)巨大。
為了保障業(yè)務(wù)高效上線,技術(shù)選型上最大化復(fù)用已有系統(tǒng)能力,避免重復(fù)造輪子。
所以,我們的技術(shù)方案是:
1)數(shù)據(jù)模型與底層存儲依賴淘系私信體系進(jìn)行建設(shè);
2)消息數(shù)據(jù)獲取上,客戶端全量從服務(wù)端拉取消息數(shù)據(jù);
3)通訊協(xié)議使用來往SDK及mtop。
總體架構(gòu)如下圖,以此模式完成快速交付保障了業(yè)務(wù)最小化可用:

4、2.0版:用戶量增速快、需要重建消息系統(tǒng)
4.1 技術(shù)背景
閑魚用戶量正快速突破100萬,即時(shí)消息服務(wù)的調(diào)用量暴漲。在這樣的背景下,用戶反饋消息數(shù)據(jù)獲取的卡頓、白屏成為常態(tài),大量的消息Push發(fā)送下,系統(tǒng)告警頻發(fā)。
造成這些問題的原因:1.0版的架構(gòu)模式下,獲取消息數(shù)據(jù)全量拉模式,客戶端純UI不做數(shù)據(jù)存儲。
具體就是:
1)當(dāng)用戶需要查看消息數(shù)據(jù)時(shí),數(shù)據(jù)拉取成功與否取決于網(wǎng)絡(luò)、數(shù)據(jù)訪問速度,偶發(fā)性的造成卡頓、白屏;
2)中心化的數(shù)據(jù)存儲,讀遠(yuǎn)大于寫,高并發(fā)下,服務(wù)端負(fù)載過大。
針對第2)點(diǎn):比如1W個(gè)用戶同時(shí)在線聊天,按照當(dāng)前架構(gòu)并發(fā)拉取全量消息,估算5萬QPS。不妨假設(shè),同時(shí)在線聊天用戶數(shù)10萬時(shí),對服務(wù)端壓力可想而知。
4.2 技術(shù)方案
基于上述問題,我們決定重建消息系統(tǒng)架構(gòu),以應(yīng)對未來更大的用戶增量。
回歸到IM系統(tǒng)的核心功能:

4.2.1)消息存儲模型:
1)會話模型:由owner、itemid、user、sessionType 來標(biāo)識唯一會話,增加擴(kuò)展屬性支持個(gè)性化;
2)摘要模型:作為用戶會話視圖,同一會話的不同用戶可個(gè)性化呈現(xiàn),由userid、sid標(biāo)識唯一摘要;
3)消息模型:由sender、消息內(nèi)容、消息版本、sid組成。sid+消息版本唯一確定一條消息;
4)指令模型:是一種雙端約定,由服務(wù)端下發(fā),客戶端執(zhí)行的指令集。如免打擾指令、刪除指令等。
4.2.2)消息通道:
1)在線通道:使用淘寶無線ACCS長連接提供的全雙工、低延時(shí)、高安全的通道服務(wù);
2)離線通道:使用淘寶消息推送平臺AGOO. 其屏蔽了各主流廠商對接的復(fù)雜度,直接對業(yè)務(wù)系統(tǒng)提供服務(wù)。
4.2.3)消息同步模型:
1)客戶端建立數(shù)據(jù)庫,存儲消息數(shù)據(jù):當(dāng)消息數(shù)據(jù)存儲在本地設(shè)備上,消息同步從全量拉取優(yōu)化為全量+增量同步結(jié)合的模式。
增量和全量同步具體指的是:
a.?增量同步:客戶端存儲消息位點(diǎn)信息,通過與服務(wù)端最新位點(diǎn)比較,僅同步增量消息;
b.?全量同步:當(dāng)用戶卸載重裝或位點(diǎn)gap過大時(shí),客戶端全量拉取歷史消息數(shù)據(jù),進(jìn)行端上數(shù)據(jù)重建。
2)服務(wù)端建設(shè)個(gè)人消息域環(huán)(收件箱模型):以和客戶端進(jìn)行增量數(shù)據(jù)同步。同時(shí),1.0版本架構(gòu)中存在的讀多寫少的問題,通過個(gè)人域環(huán)的寫擴(kuò)散來平衡讀寫壓力。
下圖為一條消息從發(fā)送到接收的過程以及服務(wù)端和客戶端的執(zhí)行流程:

如上圖所示:假設(shè)Ua給Ub發(fā)送一條消息,消息寫擴(kuò)散至Ua和Ub的各自的域環(huán)中:
1)當(dāng)客戶端online時(shí),接收到推送的消息位點(diǎn)=當(dāng)前端上域版本+1,本地消息數(shù)據(jù)庫merge即可;
2)當(dāng)客戶端offline時(shí),僅進(jìn)行離線推送通知,當(dāng)用戶重新上線時(shí),進(jìn)行數(shù)據(jù)同步,由服務(wù)端判斷觸發(fā)增量同步還是全量同步。
針對第2)點(diǎn),具體邏輯是:
1)如果域環(huán)版本差值小于閥值,增量同步后,進(jìn)行本地消息數(shù)據(jù)庫merge;
2)當(dāng)域環(huán)版本差值大于閥值,進(jìn)行全量消息拉取,做端上數(shù)據(jù)重建。
整個(gè)同步邏輯基于閑魚的即時(shí)消息域環(huán),域環(huán)可以看作是有著固定容量的用戶消息收件箱,給一個(gè)用戶發(fā)送的所有消息都會同步到他的域環(huán)中。
具體就是:
1)域環(huán)存儲:域環(huán)需要支持高并發(fā)數(shù)據(jù)讀寫,使用阿里分布式KV存儲系統(tǒng)tair來實(shí)現(xiàn);
2)域環(huán)容量:為減少全量消息同步,以用戶下次進(jìn)入閑魚需要同步的平均消息量來規(guī)劃個(gè)人域環(huán)容量。同時(shí)利用FIFO循環(huán)覆蓋歷史數(shù)據(jù);
3)域環(huán)版本:用戶當(dāng)前消息位點(diǎn),在消息進(jìn)入個(gè)人域環(huán)時(shí)通過tair的counter實(shí)現(xiàn)域環(huán)版本嚴(yán)格連續(xù)遞增,用于全量、增量同步判斷。
上述建設(shè)完成后,閑魚具備了自己獨(dú)立的即時(shí)消息系統(tǒng),當(dāng)下遇到的問題得到了緩解,用戶體驗(yàn)度有大幅提升。
5、3.0版:隨著業(yè)務(wù)快速發(fā)展,系統(tǒng)穩(wěn)定性需得到保障
5.1 技術(shù)背景
隨著閑魚業(yè)務(wù)生態(tài)的豐富,IM會話與消息內(nèi)容類型不斷擴(kuò)展,同時(shí)在用戶量的快速增長下,用戶反饋消息收不到、消息延遲等輿情問題日漸突出。

5.2 問題分析
問題1:閑魚APP進(jìn)程無有效?;顧C(jī)制,APP退到后臺后進(jìn)程很快就會被系統(tǒng)掛起,導(dǎo)致長連接中斷。此時(shí)消息推送走廠商通道,而廠商通道的實(shí)時(shí)性較差,且對消息推送的優(yōu)先級設(shè)定有差異,從而造成用戶感知消息延遲。
問題2:accs在線消息推送時(shí),平均延時(shí)較短,但存在假連情況。而且目前的消息推送鏈路無ack機(jī)制,造成服務(wù)端以為消息發(fā)出去了但實(shí)際上客戶端并沒有收到,用戶下次打開APP后才能看到消息,用戶感知消息延遲。
PS:造成假連接的原因主要是用戶退到后臺,accs長連中斷,但是設(shè)備狀態(tài)更新有延時(shí)。
問題3:目前消息同步的推模式(accs push)、拉模式(mtop),客戶端未做隔離,異步進(jìn)行處理,導(dǎo)致在某些極端情況下消息數(shù)據(jù)庫處理異常,引發(fā)消息丟失。
如:某用戶上線后連續(xù)收到多條消息,其中一條觸發(fā)域黑洞,在進(jìn)行消息同步端上數(shù)據(jù)重建時(shí),小概率處理出錯(cuò)。
問題4:大部分線上消息問題發(fā)現(xiàn)靠輿情反饋,如消息錯(cuò)亂,出問題后系統(tǒng)無感知、無補(bǔ)救措施且排查困難,僅能跟隨版本做修復(fù)。
問題5:業(yè)務(wù)不斷豐富,孵化出基于消息系統(tǒng)的服務(wù)號及小程序內(nèi)容營銷、消息群組等,各類消息發(fā)送鏈路共用域環(huán)與數(shù)據(jù)存儲,造成穩(wěn)定性問題。
如:個(gè)人域環(huán)的消息包括IM聊天和營銷消息,IM聊天由用戶觸發(fā),需要保證強(qiáng)到達(dá);而營銷消息一般是由系統(tǒng)通過班車等方式批量發(fā)送,消息量級大,tps高,影響IM服務(wù)穩(wěn)定性。
5.3 解案決方案
基于上述分析,我們逐個(gè)問題進(jìn)行專項(xiàng)解決。
1)消息重發(fā)與推拉隔離:

如上圖所示:
a.?ACK:保障消息及時(shí)到達(dá)。服務(wù)端下行accs消息時(shí),將消息加入重試隊(duì)列并延遲重試,客戶端在收到accs消息并處理成功后,給服務(wù)端回一個(gè)ack,服務(wù)端收到ack后更新消息到達(dá)狀態(tài),并終止重試,以此避免設(shè)備假連或網(wǎng)絡(luò)不穩(wěn)定的情況;
b.?重發(fā):根據(jù)延遲重發(fā)策略決定何時(shí)重發(fā)消息,保障消息確定性到達(dá)。自適應(yīng)延遲重發(fā)策略是指新消息先通過4次固定N秒的短延遲來探測設(shè)備的網(wǎng)絡(luò)狀況,然后根據(jù)網(wǎng)絡(luò)狀況來遞增固定步長M的延遲策略,這種策略可以保障在最短的時(shí)間內(nèi),使用最少的重發(fā)次數(shù)將消息投遞成功;
c.?消息隊(duì)列:端上引入消息隊(duì)列,按順序處理消息,保證消息處理的準(zhǔn)確性。同時(shí)進(jìn)行推拉隔離,保障隊(duì)列有序消費(fèi),解決了復(fù)雜狀況下并發(fā)處理消息數(shù)據(jù)合并出錯(cuò)的問題。
2)數(shù)據(jù)存儲拆分:
閑魚每天發(fā)送的即時(shí)消息中有一半以上是營銷消息,營銷消息的發(fā)送具有明顯的波峰波谷流量,高峰期會導(dǎo)致消息數(shù)據(jù)庫抖動(dòng),影響IM消息。我來對消息、摘要、域環(huán)存儲做業(yè)務(wù)隔離,以適應(yīng)不同業(yè)務(wù)場景對穩(wěn)定性不同的要求。
具體做法是:
1)IM消息需要極高的穩(wěn)定性保證,其消息及摘要繼續(xù)使用mysql存儲;
2)營銷消息存儲周期短,穩(wěn)定性要求低于IM,采用Lindorm存儲;
3)域環(huán)做實(shí)例級別隔離,保證IM域環(huán)的容量不會被其他消息占用,從而影響到消息同步。
PS:Lindorm是一種多模型的云原生數(shù)據(jù)庫服務(wù),具有成本低、自定義TTL、容量橫向擴(kuò)展等優(yōu)勢。

3)線上問題發(fā)現(xiàn)與恢復(fù):
保障穩(wěn)定性的關(guān)鍵要素是做好各種核心指標(biāo)的監(jiān)控,而監(jiān)控首先要有數(shù)據(jù)來源,對服務(wù)端+客戶端的關(guān)鍵鏈路節(jié)點(diǎn)埋點(diǎn),基于集團(tuán)UT、SLS,通過blink進(jìn)行實(shí)時(shí)清洗、計(jì)算,最終形成統(tǒng)一規(guī)范的日志數(shù)據(jù)落至SLS,以供實(shí)時(shí)監(jiān)控及鏈路排查。
消息系統(tǒng)的核心目標(biāo)是保障用戶消息發(fā)的出、收得到且及時(shí)收到,所以我們通過計(jì)算發(fā)送成功率、到達(dá)率、消息延遲來監(jiān)控系統(tǒng)的穩(wěn)定性。
此外,為了解決用戶輿情排查困難的問題:
1)我們設(shè)計(jì)了一套指令集,通過約定指令協(xié)議,服務(wù)端向指定用戶下發(fā)指令,客戶端執(zhí)行對應(yīng)指令進(jìn)行異常數(shù)據(jù)上報(bào),提高排查效率;
2)擴(kuò)展了強(qiáng)制全量同步、數(shù)據(jù)校正等指令,定向修復(fù)用戶消息數(shù)據(jù)問題,相較以往出現(xiàn)嚴(yán)重bug只能讓用戶卸載重裝解決,這種方式顯然對用戶是更友好的。

經(jīng)過一系列專項(xiàng)治理,技術(shù)類輿情下降50%,從0到1建設(shè)了消息穩(wěn)定性體系,用戶體驗(yàn)進(jìn)一步提升。
6、展望未來
閑魚作為電商交易APP, 其中IM是交易的前置鏈路,IM的產(chǎn)品體驗(yàn)極大影響用戶交易效率。
前段時(shí)間進(jìn)行用戶調(diào)研,從閑魚IM的NPS低于預(yù)期(NPS是用戶忠誠度衡量指標(biāo) = 推薦者%-貶損者%)。
從用戶反饋來看:
1)部分用戶對產(chǎn)品功能有較強(qiáng)烈的訴求,諸如消息搜索、分組等;
2)大部分用戶對發(fā)送消息過程中的違規(guī)問題難以理解;
3)仍有較多輿情反饋消息收不到或延遲。
映射到目前閑魚的即時(shí)消息系統(tǒng)上,我們的系統(tǒng)架構(gòu)依然有很多需要持續(xù)改進(jìn)的地方。
典型的如:同步協(xié)議冗余,在需求迭代過程中容易引發(fā)問題、有效?;顧C(jī)制的缺失對消息即時(shí)送達(dá)的影響、小眾機(jī)型離線消息收不到、多年的數(shù)據(jù)積累在線庫臃腫等問題,影響著閑魚業(yè)務(wù)迭代速度與NPS。
作為技術(shù)團(tuán)隊(duì),下一步將提升NPS作為核心技術(shù)目標(biāo),閑魚的即時(shí)消息系統(tǒng)4.0版架構(gòu)正在路上 ......
附錄:更多相關(guān)文章
[1] 更多阿里巴巴的技術(shù)資源:
《阿里釘釘技術(shù)分享:企業(yè)級IM王者——釘釘在后端架構(gòu)上的過人之處》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討》
《阿里技術(shù)分享:深度揭秘阿里數(shù)據(jù)庫技術(shù)方案的10年變遷史》
《阿里技術(shù)分享:阿里自研金融級數(shù)據(jù)庫OceanBase的艱辛成長之路》
《來自阿里OpenIM:打造安全可靠即時(shí)通訊服務(wù)的技術(shù)實(shí)踐分享》
《釘釘——基于IM技術(shù)的新一代企業(yè)OA平臺的技術(shù)挑戰(zhàn)(視頻+PPT) [附件下載]》
《阿里技術(shù)結(jié)晶:《阿里巴巴Java開發(fā)手冊(規(guī)約)-華山版》[附件下載]》
《重磅發(fā)布:《阿里巴巴Android開發(fā)手冊(規(guī)約)》[附件下載]》
《作者談《阿里巴巴Java開發(fā)手冊(規(guī)約)》背后的故事》
《《阿里巴巴Android開發(fā)手冊(規(guī)約)》背后的故事》
《干了這碗雞湯:從理發(fā)店小弟到阿里P10技術(shù)大?!?/p>
《揭秘阿里、騰訊、華為、百度的職級和薪酬體系》
《淘寶技術(shù)分享:手淘億級移動(dòng)端接入層網(wǎng)關(guān)的技術(shù)演進(jìn)之路》
《難得干貨,揭秘支付寶的2維碼掃碼技術(shù)優(yōu)化實(shí)踐之路》
《淘寶直播技術(shù)干貨:高清、低延時(shí)的實(shí)時(shí)視頻直播技術(shù)解密》
《阿里技術(shù)分享:電商IM消息平臺,在群聊、直播場景下的技術(shù)實(shí)踐》
《阿里技術(shù)分享:閑魚IM基于Flutter的移動(dòng)端跨端改造實(shí)踐》
《阿里IM技術(shù)分享(三):閑魚億級IM消息系統(tǒng)的架構(gòu)演進(jìn)之路》
?
[2] 有關(guān)IM架構(gòu)設(shè)計(jì)的文章:
《淺談IM系統(tǒng)的架構(gòu)設(shè)計(jì)》
《簡述移動(dòng)端IM開發(fā)的那些坑:架構(gòu)設(shè)計(jì)、通信協(xié)議和客戶端》
《一套海量在線用戶的移動(dòng)端IM架構(gòu)設(shè)計(jì)實(shí)踐分享(含詳細(xì)圖文)》
《一套原創(chuàng)分布式即時(shí)通訊(IM)系統(tǒng)理論架構(gòu)方案》
《從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程》
《蘑菇街即時(shí)通訊/IM服務(wù)器開發(fā)之架構(gòu)選擇》
《騰訊QQ1.4億在線用戶的技術(shù)挑戰(zhàn)和架構(gòu)演進(jìn)之路PPT》
《微信后臺基于時(shí)間序的海量數(shù)據(jù)冷熱分級架構(gòu)設(shè)計(jì)實(shí)踐》
《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡(演講全文)》
《如何解讀《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡》》
《快速裂變:見證微信強(qiáng)大后臺架構(gòu)從0到1的演進(jìn)歷程(一)》
《移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討》
《微信朋友圈千億訪問量背后的技術(shù)挑戰(zhàn)和實(shí)踐總結(jié)》
《子彈短信光鮮的背后:網(wǎng)易云信首席架構(gòu)師分享億級IM平臺的技術(shù)實(shí)踐》
《微信技術(shù)分享:微信的海量IM聊天消息序列號生成實(shí)踐(算法原理篇)》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐》
《社交軟件紅包技術(shù)解密(一):全面解密QQ紅包技術(shù)方案——架構(gòu)、技術(shù)實(shí)現(xiàn)等》
《從游擊隊(duì)到正規(guī)軍(一):馬蜂窩旅游網(wǎng)的IM系統(tǒng)架構(gòu)演進(jìn)之路》
《從游擊隊(duì)到正規(guī)軍(二):馬蜂窩旅游網(wǎng)的IM客戶端架構(gòu)演進(jìn)和實(shí)踐總結(jié)》
《從游擊隊(duì)到正規(guī)軍(三):基于Go的馬蜂窩旅游網(wǎng)分布式IM系統(tǒng)技術(shù)實(shí)踐》
《瓜子IM智能客服系統(tǒng)的數(shù)據(jù)架構(gòu)設(shè)計(jì)(整理自現(xiàn)場演講,有配套PPT)》
《IM開發(fā)基礎(chǔ)知識補(bǔ)課(九):想開發(fā)IM集群?先搞懂什么是RPC!》
《阿里技術(shù)分享:電商IM消息平臺,在群聊、直播場景下的技術(shù)實(shí)踐》
《一套億級用戶的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等》
《一套億級用戶的IM架構(gòu)技術(shù)干貨(下篇):可靠性、有序性、弱網(wǎng)優(yōu)化等》
《從新手到專家:如何設(shè)計(jì)一套億級消息量的分布式IM系統(tǒng)》
《企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬人群、已讀回執(zhí)、消息撤回等》
《融云技術(shù)分享:全面揭秘億級IM消息的可靠投遞機(jī)制》
《IM開發(fā)技術(shù)學(xué)習(xí):揭秘微信朋友圈這種信息推流背后的系統(tǒng)設(shè)計(jì)》
《阿里IM技術(shù)分享(三):閑魚億級IM消息系統(tǒng)的架構(gòu)演進(jìn)之路》
>>?更多同類文章 ……
本文已同步發(fā)布于“即時(shí)通訊技術(shù)圈”公眾號。
同步發(fā)布鏈接是:http://www.52im.net/thread-3699-1-1.html?