得物從0到1自研客服IM系統(tǒng)的技術(shù)實(shí)踐之路

本文由得物技術(shù)王衛(wèi)強(qiáng)分享,為了更好的閱讀體驗(yàn),有較多的內(nèi)容修訂和排版優(yōu)化。
一、引言
客服IM的核心業(yè)務(wù)其實(shí)就是在線溝通,客服IM的好處是使得客服與用戶通過(guò)實(shí)時(shí)溝通的方式可以在最短的時(shí)間內(nèi)幫助用戶解決問(wèn)題。
為了快速支撐公司業(yè)務(wù)發(fā)展需求,我們客服IM在發(fā)展初期是基于第三方的云IM SDK進(jìn)行二次開(kāi)發(fā)而來(lái)。雖然提升了項(xiàng)目進(jìn)展,但同時(shí)也埋下了問(wèn)題定位困難、特殊功能實(shí)現(xiàn)成本高等隱患。
隨著公司業(yè)務(wù)的高速發(fā)展,客服對(duì)IM聊天的性能和體驗(yàn)都有了更高的要求,在第三方云IM SDK消息通信上逐漸遇到了技術(shù)瓶頸。為解決租用第三方云IM SDK接入帶來(lái)的潛在隱患、提升IM的穩(wěn)定性和高擴(kuò)展性,自研一套可控、穩(wěn)定、靈活的IM系統(tǒng)已是迫在眉睫了。
本篇文章將基于工程實(shí)踐,分享我們從0到1自研一套客服IM系統(tǒng)時(shí)在各種關(guān)鍵技術(shù)點(diǎn)上的設(shè)計(jì)思路和實(shí)踐方法。

注:為了簡(jiǎn)化內(nèi)容,本文分享的技術(shù)棧主要是以Web客服端為主。
相關(guān)文章:
1)從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程;
2)瓜子IM智能客服系統(tǒng)的數(shù)據(jù)架構(gòu)設(shè)計(jì)(整理自現(xiàn)場(chǎng)演講,有配套PPT)。
學(xué)習(xí)交流:
- 移動(dòng)端IM開(kāi)發(fā)入門文章:《新手入門一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》
- 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點(diǎn)此)
(本文已同步發(fā)布于:http://www.52im.net/thread-4153-1-1.html)
二、業(yè)務(wù)場(chǎng)景
客服與用戶在聊天的過(guò)程中,直觀上就是客服在輸入文案,然后通過(guò)網(wǎng)絡(luò)發(fā)送給用戶。
但是IM聊天SDK該如何設(shè)計(jì)才能使客服在發(fā)送消息過(guò)程中感知不到卡頓?這一點(diǎn)是非常關(guān)鍵的,要避免卡頓就要設(shè)計(jì)合理的發(fā)送策略以及避免大量JS腳本執(zhí)行。
舉個(gè)客服與用戶聊天的例子:
1)客服發(fā)送了“客服小冰為您服務(wù)”這個(gè)文案,通過(guò)業(yè)務(wù)側(cè)調(diào)用SDK的接口,傳入到SDK;
2)再將該數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)池中,序列化后把這個(gè)數(shù)據(jù)對(duì)象data傳遞給socket接口,通過(guò)網(wǎng)絡(luò)通道發(fā)送到網(wǎng)關(guān);
3)網(wǎng)關(guān)側(cè)接收到消息后,再反序列化,傳遞到數(shù)據(jù)池中進(jìn)行處理,組裝成業(yè)務(wù)可識(shí)別的model,推送到業(yè)務(wù)側(cè)使用。
針對(duì)第1)點(diǎn),SDK會(huì)先創(chuàng)建消息體,即把這個(gè)字符串封裝成一個(gè)自定義的結(jié)構(gòu)體model。
其聊天流程如下圖所示:

從上圖中可以清晰的看出一條消息發(fā)送和接收的完整流程鏈路。如果IM的SDK設(shè)計(jì)不合理,發(fā)送消息和接收消息流程出現(xiàn)了卡頓,將直接影響用戶的體驗(yàn)。
三、自研框架架構(gòu)圖概覽
下圖是我們的自研IM系統(tǒng)架構(gòu)原理圖:

我們整體的技術(shù)改造主要是兩個(gè)方面:
1)對(duì)消息鏈路的抽象改造:主要是消息數(shù)據(jù)存儲(chǔ)和消息排序的重構(gòu);
2)業(yè)務(wù)接入側(cè)的抽象改造:主要是將業(yè)務(wù)邏輯和SDK源碼進(jìn)行解耦,做到代碼分層更加的清晰。
下面我們將針對(duì)主要的技術(shù)點(diǎn)進(jìn)行詳細(xì)地總結(jié)和分享。
四、消息鏈路發(fā)布/訂閱實(shí)現(xiàn)
在IM SDK自研開(kāi)發(fā)過(guò)程中,如何解耦框架代碼和業(yè)務(wù)代碼,做到靈活的消息監(jiān)聽(tīng),前期調(diào)研之后使用了RxJS。
這里簡(jiǎn)單介紹幾個(gè)RxJS的核心概念:
1)Observable(可觀察對(duì)象):表示一個(gè)可調(diào)用的未來(lái)值或事件的集合;
2)Observer(觀察者):監(jiān)聽(tīng)由Observable提供的值;
3)Subscription?(訂閱):表示 Observable 的執(zhí)行。
注:Subscription 有一個(gè)重要的方法,即 unsubscribe,它不需要任何參數(shù),只是用來(lái)清理由 Subscription 占用的資源主要用于取消 Observable 的執(zhí)行。
SDK底層在接收到數(shù)據(jù)后需要同步到業(yè)務(wù)側(cè),之前的做法是通過(guò)監(jiān)聽(tīng)方式實(shí)現(xiàn),這種方式不具備取消訂閱的能力,維護(hù)成本相對(duì)較高。而使用RxJS可以清晰的梳理出數(shù)據(jù)流向,通過(guò)發(fā)布訂閱的方式實(shí)現(xiàn)數(shù)據(jù)的通信。
RxJS在發(fā)布訂閱的實(shí)現(xiàn)流程如下:

從上圖可以看到消息處理的整個(gè)流向非常清晰,框架底層接收消息,訂閱者消費(fèi)消息。
五、消息框架的分層結(jié)構(gòu)概覽
在我們整個(gè)自研的IM消息通信框架中,主要結(jié)構(gòu)分成三層:
1)網(wǎng)絡(luò)層;
2)數(shù)據(jù)鏈路層;
3)應(yīng)用層。
具體如下圖所示:

接下來(lái)我將詳細(xì)分享各層的設(shè)計(jì)和實(shí)現(xiàn)思路。
六、消息框架的分層實(shí)現(xiàn):網(wǎng)絡(luò)層
網(wǎng)絡(luò)層作為消息發(fā)送的最底層,負(fù)責(zé)TCP的連接、消息發(fā)送和接收。
網(wǎng)絡(luò)協(xié)議我們選擇的是TCP協(xié)議。我們?yōu)槭裁礇](méi)有選擇UDP呢?因?yàn)閁DP是無(wú)連接的、不夠安全、無(wú)法提供可靠傳輸?shù)姆?wù),通過(guò)TCP連接傳送的數(shù)據(jù)可以無(wú)差別、不丟失、不重復(fù)且按序到達(dá)。
PS:尺有所短、寸有所長(zhǎng),TCP和UDP的優(yōu)劣應(yīng)該客觀看待,感興趣可以深入學(xué)習(xí)下面的文章:
《快速理解TCP和UDP的差異》
《一泡尿的時(shí)間,快速搞懂TCP和UDP的區(qū)別》
《快速理解為什么說(shuō)UDP有時(shí)比TCP更有優(yōu)勢(shì)》
《深入地理解UDP協(xié)議并用好它》
《如何讓不可靠的UDP變的可靠?》
我們整個(gè)IM SDK的通信方式采用的是?WebSocket?+ JSON、grpc +?protobuf。(如果你對(duì)WebSocket和Protobuf不熟悉,可以詳細(xì)學(xué)習(xí)《WebSocket從入門到精通,半小時(shí)就夠!》、《Protobuf從入門到精通,一篇就夠!》)
首先我們要做的就是建立Websocket連接:代碼層面我們會(huì)先創(chuàng)建一個(gè)Connection的抽象類,主要處理網(wǎng)絡(luò)連接相關(guān)配置、超時(shí)后重新連接的補(bǔ)償實(shí)現(xiàn),和一些繼承類需要實(shí)現(xiàn)的抽象方法。

如上述代碼所示:核心在處理超時(shí)重連,傳統(tǒng)的重試策略是每隔一段時(shí)間重試一次,由于是固定的時(shí)間間隔重試,重試時(shí)又會(huì)有大量的請(qǐng)求在同一時(shí)刻涌入,會(huì)不斷地造成限流。(這里使用了指數(shù)退避的方式,指數(shù)退避是一種通過(guò)反饋,成倍地降低某個(gè)過(guò)程的速率,以逐漸找到合適速率的算法,可根據(jù)時(shí)隙和重試嘗試次數(shù)來(lái)決定延遲重試。)
其實(shí)現(xiàn)算法大致如下:

Websocket連接我們是通過(guò)繼承Connect類實(shí)現(xiàn)的:

至此:網(wǎng)絡(luò)層連接就已完成了,相對(duì)比較簡(jiǎn)單,都是一些socket api的封裝,核心的點(diǎn)在用指數(shù)退避算法實(shí)現(xiàn)消息發(fā)送失敗重連接。
七、消息框架的分層實(shí)現(xiàn):數(shù)據(jù)鏈路層
數(shù)據(jù)鏈路層是IM SDK的核心層,主要涉及到用戶信息、聊天消息、數(shù)據(jù)池等等,我們來(lái)一步步對(duì)每個(gè)模塊進(jìn)行分析。
首先梳理一下客服在登錄到用戶進(jìn)線發(fā)送消息和接收消息的全過(guò)程。
過(guò)程有如下幾個(gè)階段:

7.1、協(xié)議類型
消息協(xié)議類型非常重要,是消息發(fā)送的基石。初始化協(xié)議數(shù)據(jù)體,可以用于后續(xù)各種消息、事件的發(fā)送。
在IM自研的SDK通信協(xié)議類型主要有如下幾種:


具體解釋一下:
1)Hi:發(fā)送客戶端基礎(chǔ)信息,告訴server當(dāng)前client的版本、設(shè)備類型、語(yǔ)言等信息;
2)Login: 登錄,token驗(yàn)證,獲取或創(chuàng)建當(dāng)前用戶topic信息;
3)Sub: 訂閱topic或更新topic數(shù)據(jù);
4)Leave: 取消訂閱,解綁之前的訂閱關(guān)系;
5)Pub: 發(fā)送數(shù)據(jù)消息給指定topic的訂閱者;
6)Get: 獲取topic的metadata信息,例如:獲取訂閱者列表、歷史數(shù)據(jù)等;
7)Set: 更新topic的metadata信息,例如:刪除消息或刪除topic;
8)Del: 用于刪除操作,包括刪除消息、刪除訂閱關(guān)系、刪除topic等;
9)Note: client發(fā)送通知給topic的訂閱者,例如消息已收到,消息已讀,當(dāng)前正在輸入等;
10)Action: 觸發(fā)的事件,例如:切換客服狀態(tài)、獲取機(jī)器人問(wèn)題等;
11)Datares: ack機(jī)制,告訴網(wǎng)關(guān)已收到該消息。
7.2、創(chuàng)建連接
對(duì)網(wǎng)絡(luò)層消息鏈接實(shí)例化,實(shí)現(xiàn)消息的正常發(fā)送和接收。
其實(shí)現(xiàn)如下:

7.3、消息定義
客服要發(fā)送一條消息,肯定有對(duì)應(yīng)的消息結(jié)構(gòu)體model,即需要對(duì)消息體進(jìn)行設(shè)計(jì),這里會(huì)設(shè)計(jì)一下message類,每次創(chuàng)建新的消息體都會(huì)new一個(gè)實(shí)例,通過(guò)對(duì)實(shí)例的操作可以更新消息狀態(tài)等。
如下所示:

針對(duì)單個(gè)消息,我們也要定義好消息狀態(tài),用于聊天過(guò)程中消息狀態(tài)的更新。
如下:

7.4、數(shù)據(jù)池
消息類創(chuàng)建好之后,就需要有消息數(shù)據(jù)池來(lái)存儲(chǔ)。
消息池結(jié)構(gòu)定義如下:

這里還涉及到消息體的一些基本操作方法對(duì)數(shù)據(jù)池中的數(shù)據(jù)進(jìn)行操作,就不做過(guò)多的闡述。
7.5、用戶維度
上面都是在分析公共模塊,但是客服和用戶是一對(duì)多的關(guān)系存在,還需要設(shè)計(jì)一個(gè)用戶維度模塊,后續(xù)在業(yè)務(wù)側(cè)的操作基本都是以用戶維度來(lái)操作,需要從單個(gè)用戶維度設(shè)計(jì)對(duì)應(yīng)的訂閱關(guān)系、消息發(fā)送、刪除等等。
其實(shí)現(xiàn)大致如下:

7.5.1發(fā)送消息鏈路分析
針對(duì)客服發(fā)送消息,我們首先要站在客服角度考慮消息是否已發(fā)出去,優(yōu)先展示的聊天頁(yè)面,而不是等網(wǎng)關(guān)給了回復(fù)后在展示到聊天頁(yè)面。
根據(jù)已往經(jīng)驗(yàn)來(lái)看,只要回車消息就要立即展示到聊天頁(yè)面,否則客服會(huì)認(rèn)為出現(xiàn)了卡頓,體驗(yàn)效果不佳,鑒于這種場(chǎng)景的需求,在設(shè)計(jì)發(fā)送消息鏈路的時(shí)候就要充分考慮到這一點(diǎn)。
所以設(shè)計(jì)流程如下:

如上圖所示:先在SDK內(nèi)進(jìn)行處理對(duì)應(yīng)的消息,處理完成后返回到業(yè)務(wù)側(cè)完成渲染后再進(jìn)行消息發(fā)送到網(wǎng)關(guān),正常情況下都在一幀之內(nèi),客服是感知不到有延遲的。這里要關(guān)注消息體序列化、反序列化的時(shí)機(jī),避免無(wú)謂的性能浪費(fèi)。
上述圖中有個(gè)虛擬seq:主要是為了在未收到IM網(wǎng)關(guān)響應(yīng)之前進(jìn)行排序用的,比如圖片、視頻、斷網(wǎng)發(fā)送消息、消息發(fā)送失敗,或收到IM網(wǎng)關(guān)回復(fù)缺少seq(場(chǎng)景:敏感詞)等情況都需要通過(guò)虛擬seq進(jìn)行準(zhǔn)確排序。
7.5.2接收消息鏈路分析
接收消息過(guò)程相對(duì)比較簡(jiǎn)單,收到消息進(jìn)行反序列化后更新相關(guān)數(shù)據(jù),然后在數(shù)據(jù)池中完成去重(重試機(jī)制)、排序后更新到業(yè)務(wù)側(cè)渲染即可(如下圖所示)。

7.5.3消息的可靠傳遞
IM消息的可靠投遞主要是指:消息在發(fā)送接收過(guò)程中,能夠做到不丟消息、消息不重復(fù)、消息順序不錯(cuò)亂。
我們先來(lái)分析以下2種情況。
第一種情況:如果客服A在把消息發(fā)送到IM網(wǎng)關(guān)的過(guò)程中:
1)由于網(wǎng)絡(luò)不通等原因失敗了;
2)或者IM網(wǎng)關(guān)接收到消息進(jìn)行存儲(chǔ)時(shí)失敗了;
3)或者IM網(wǎng)關(guān)一直沒(méi)有返回結(jié)果,導(dǎo)致超時(shí)。
以上這些情況客服A都會(huì)被提示消息發(fā)送失敗。
第二種情況:消息在IM網(wǎng)關(guān)存儲(chǔ)完后,客服A被告知消息發(fā)送成功了,然后IM網(wǎng)關(guān)把消息推送給用戶A的在線設(shè)備:
1)在推送的準(zhǔn)備階段或者把消息寫(xiě)入到內(nèi)存后,如果服務(wù)端出現(xiàn)掉電,也會(huì)導(dǎo)致消息不能成功推送給用戶A;
2)如果用戶A的設(shè)備在接收到消息,在后續(xù)處理過(guò)程中出現(xiàn)問(wèn)題,也會(huì)導(dǎo)致消息丟失。
針對(duì)第2)點(diǎn),具體場(chǎng)景比如:用戶A的設(shè)備在把消息寫(xiě)入本地DB時(shí),出現(xiàn)異常導(dǎo)致落庫(kù)失敗,這種情況下,由于網(wǎng)絡(luò)層面實(shí)際上已經(jīng)成功傳輸,但用戶A卻看不到消息。
我們客服IM對(duì)于消息丟失的處理方案主要是參考TCP協(xié)議的ACK機(jī)制,實(shí)現(xiàn)了一套基于業(yè)務(wù)層的ACK協(xié)議。
添加ACK之前消息發(fā)送的時(shí)序圖如下:

7.5.3.1)ACK 機(jī)制:
在TCP協(xié)議中,默認(rèn)提供了ACK機(jī)制,通過(guò)一個(gè)協(xié)議自帶的標(biāo)準(zhǔn)的ACK數(shù)據(jù)包,來(lái)對(duì)通信方接收的數(shù)據(jù)進(jìn)行確認(rèn),告知通信發(fā)送方已確認(rèn)成功接收了數(shù)據(jù)。ACK機(jī)制也是類似,需要解決的是:IM網(wǎng)關(guān)推送后如何確認(rèn)消息是否成功送達(dá)接收方并明確被接收方所接收。
具體實(shí)現(xiàn)的時(shí)序圖如下:

客服或用戶在發(fā)送消息的過(guò)程中都會(huì)攜帶一個(gè)msgid(32位的uuid,類似TCP的sequenceId),IM網(wǎng)關(guān)在接收到消息后,會(huì)根據(jù)msgid到數(shù)據(jù)庫(kù)中查詢是否存在該條消息,如果存在就不落庫(kù),如果不存在就落庫(kù)。
然后再推送到接收方,接收方在收到消息后會(huì)回復(fù)ACK,ACK包中會(huì)攜帶上當(dāng)前最新的seqid,IM網(wǎng)關(guān)收到ACK回復(fù)后會(huì)對(duì)最大的seqid進(jìn)行更新。
這里為什么要更新最大seqid呢?這么設(shè)計(jì)肯定有一定道理的,IM網(wǎng)關(guān)在收到發(fā)送方發(fā)送的消息后除了到數(shù)據(jù)庫(kù)中檢測(cè)該消息是否存在外,還會(huì)對(duì)比當(dāng)前接收到消息的seq和最大seqid兩者之間的差值,會(huì)把?[seq, seqid)?之間的數(shù)據(jù)全部推到接收方,正常情況下都是?[n, n-1),如果IM網(wǎng)關(guān)沒(méi)有收到接收方ACK,n-1就不會(huì)更新,推送的消息個(gè)數(shù)就大于1了。如果seq和seqid相等那就是發(fā)送方重復(fù)推送的消息,這個(gè)時(shí)候就不會(huì)向接收方推送。這里就涉及到了消息重試,繼續(xù)向下分析吧。
PS:有關(guān)IM消息ID或序列號(hào)生成的專題文章可以閱讀:
《IM消息ID技術(shù)專題(一):微信的海量IM聊天消息序列號(hào)生成實(shí)踐(算法原理篇)》
《IM消息ID技術(shù)專題(三):解密融云IM產(chǎn)品的聊天消息ID生成策略》
《IM消息ID技術(shù)專題(四):深度解密美團(tuán)的分布式ID生成算法》
《IM消息ID技術(shù)專題(五):開(kāi)源分布式ID生成器UidGenerator的技術(shù)實(shí)現(xiàn)》
《IM消息ID技術(shù)專題(六):深度解密滴滴的高性能ID生成器(Tinyid)》
7.5.3.2)ACK機(jī)制中的消息重試:
消息推給A的過(guò)程中丟失了怎么辦,比如:
1)A網(wǎng)絡(luò)實(shí)際已經(jīng)不可達(dá),但I(xiàn)M網(wǎng)關(guān)還沒(méi)有感知到(ping出現(xiàn)問(wèn)題);
2)消息在中間網(wǎng)絡(luò)途中被某些中間設(shè)備丟掉了。
解決這個(gè)問(wèn)題也是參考了TCP協(xié)議的重傳機(jī)制。我們會(huì)在客服端、IM網(wǎng)關(guān)、用戶端都維護(hù)一個(gè)超時(shí)計(jì)時(shí)器,一定時(shí)間內(nèi)如果沒(méi)有收到對(duì)方回的ACK包,會(huì)重新取出該消息進(jìn)行重推。在重試一定次數(shù)后,如果還是沒(méi)有收到ACK,視為放棄。
前端代碼結(jié)構(gòu)和效果如下:
上述圖片中的數(shù)據(jù)只是模擬消息重試,真實(shí)場(chǎng)景中執(zhí)行頻次肯定要比這個(gè)時(shí)間更久一些。
7.5.3.3)消息重復(fù)推送的問(wèn)題:
如果在一定時(shí)間內(nèi)沒(méi)有收到ACK包,就會(huì)觸發(fā)重試機(jī)制。收不到ACK的情況有兩種,除了推送的消息真正丟失導(dǎo)致A不回ACK外,還可能是A回的ACK包本身丟了。
解決方案是:發(fā)送方在發(fā)送消息時(shí)攜帶一個(gè)msgid,msgid是全局唯一的,針對(duì)同一條重推的消息msgid不變,接收方根據(jù)這個(gè)唯一的msgid進(jìn)行去重,這樣經(jīng)過(guò)去重后,對(duì)于A來(lái)說(shuō),在聊天界面是不會(huì)看到重復(fù)的消息,不影響使用體驗(yàn)。
7.5.3.4)保證消息不會(huì)亂序:
消息的一致性是非常重要的,在聊天過(guò)程中消息順序不能錯(cuò)亂。
我們是這樣考慮的:
1)以發(fā)送方的本地時(shí)間戳為序號(hào),但是這樣有比較大的問(wèn)題,發(fā)送方的時(shí)間戳是可以被改動(dòng)的,這種方式不可??;
2)IM網(wǎng)關(guān)服務(wù)是集群部署,會(huì)通過(guò)topic和seqid做為唯一索引,在接收到消息落庫(kù)之前會(huì)生成seqid,客服端和用戶端接收到發(fā)送消息的回執(zhí)時(shí)需要根據(jù)返回的seqid(IM網(wǎng)關(guān)自增)進(jìn)行消息排序,這種方式可取。
通過(guò)以上的分析:客服IM消息的可靠性就是通過(guò)ACK機(jī)制、重試機(jī)制、去重機(jī)制、排序機(jī)制來(lái)確保每一條消息的完整觸達(dá)和準(zhǔn)確排序。
八、消息框架的分層實(shí)現(xiàn):應(yīng)用層
業(yè)務(wù)側(cè)使用的時(shí)候直接實(shí)例化SDK即可,在消息鏈路發(fā)布訂閱中已經(jīng)提到了RxJS,此時(shí)在業(yè)務(wù)側(cè)訂閱使用即可。
需要注意的是在實(shí)例化SDK的時(shí)候傳遞了一個(gè)filterMsgItem方法,主要是為特殊業(yè)務(wù)場(chǎng)景提供使用的。
就拿我們客服業(yè)務(wù)來(lái)說(shuō):有些特定消息是不需要展示到聊天頁(yè)面的(比如:用戶發(fā)送消息被篡改等)。當(dāng)然我們?cè)跇I(yè)務(wù)側(cè)重新對(duì)數(shù)據(jù)過(guò)濾或者渲染的時(shí)候也是可以做過(guò)濾的,這樣操作是沒(méi)什么問(wèn)題,但是沒(méi)有必要,如果不從源頭過(guò)濾數(shù)據(jù),后續(xù)參與二分、倒序查找的源數(shù)據(jù)也會(huì)增加。會(huì)有一些不必要的浪費(fèi)。當(dāng)然也可以不添加這個(gè)參數(shù),SDK都是全兼容的。
至此我們就完成了整個(gè)SDK的實(shí)現(xiàn)以及在業(yè)務(wù)側(cè)的使用,消息發(fā)送和接收也都正常。
效果如下:
九、本文小結(jié)
自研IM SDK還是蠻有挑戰(zhàn)的一件事情,從單純的基于第三方SDK二次開(kāi)發(fā)到自研SDK并與我們的實(shí)際業(yè)務(wù)場(chǎng)景相對(duì)完美的結(jié)合。
在SDK的整體設(shè)計(jì)以及和業(yè)務(wù)側(cè)如何更完美的結(jié)合并不是一蹴而就的,都是在實(shí)際業(yè)務(wù)場(chǎng)景中不斷積累經(jīng)驗(yàn),不斷嘗試才找到相對(duì)完美的解決方案。
這里列舉一個(gè)簡(jiǎn)單的案例吧。
例如消息發(fā)送,需要考慮到斷網(wǎng)場(chǎng)景下:
1)該如何進(jìn)行消息顯示、排序、重新發(fā)送?
2)發(fā)送失敗的場(chǎng)景下重新發(fā)送再次失敗后又該如何顯示、排序?
3)弱網(wǎng)場(chǎng)景下發(fā)送消息觸發(fā)重試機(jī)制該如何以最優(yōu)的方式去重、排序?
4)發(fā)送消息觸發(fā)敏感詞該如何處理?
5)斷網(wǎng)重連后對(duì)于發(fā)送失敗和觸發(fā)敏感詞的消息又該如何處理?
6)如果在涉及到文件又該如何處理?
……
在自研過(guò)程中除了關(guān)注業(yè)務(wù)場(chǎng)景外,還調(diào)研了行業(yè)內(nèi)比較好的一些Web應(yīng)用在某些特殊場(chǎng)景的處理方式。很多優(yōu)秀的方案也都只能是借鑒一些核心思想,還是要以業(yè)務(wù)為核心,真正通過(guò)技術(shù)手段解決業(yè)務(wù)痛點(diǎn)才是最重要的。
自研SDK收益還是非常大的,也積累了很多IM方面的經(jīng)驗(yàn),完成自研IM SDK也只是一個(gè)開(kāi)始,后續(xù)我們將會(huì)在耗時(shí)任務(wù)、數(shù)據(jù)安全等方面持續(xù)深耕細(xì)作。
十、參考資料
[1]?從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程
[2]?瓜子IM智能客服系統(tǒng)的數(shù)據(jù)架構(gòu)設(shè)計(jì)(整理自現(xiàn)場(chǎng)演講,有配套PPT)
[3]?從游擊隊(duì)到正規(guī)軍(一):馬蜂窩旅游網(wǎng)的IM系統(tǒng)架構(gòu)演進(jìn)之路
[4]?一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐
[5]?淺談IM系統(tǒng)的架構(gòu)設(shè)計(jì)
[6]?簡(jiǎn)述移動(dòng)端IM開(kāi)發(fā)的那些坑:架構(gòu)設(shè)計(jì)、通信協(xié)議和客戶端
[7]?一套海量在線用戶的移動(dòng)端IM架構(gòu)設(shè)計(jì)實(shí)踐分享(含詳細(xì)圖文)
[8]?一套原創(chuàng)分布式即時(shí)通訊(IM)系統(tǒng)理論架構(gòu)方案
[9]?一套億級(jí)用戶的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等
[10]?從新手到專家:如何設(shè)計(jì)一套億級(jí)消息量的分布式IM系統(tǒng)
[11]?企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬(wàn)人群、已讀回執(zhí)、消息撤回等
[12]?阿里IM技術(shù)分享(三):閑魚(yú)億級(jí)IM消息系統(tǒng)的架構(gòu)演進(jìn)之路
[13]?基于實(shí)踐:一套百萬(wàn)消息量小規(guī)模IM系統(tǒng)技術(shù)要點(diǎn)總結(jié)
[14]?跟著源碼學(xué)IM(十):基于Netty,搭建高性能IM集群(含技術(shù)思路+源碼)
[15]?一套十萬(wàn)級(jí)TPS的IM綜合消息系統(tǒng)的架構(gòu)實(shí)踐與思考
[16]?直播系統(tǒng)聊天技術(shù)(八):vivo直播系統(tǒng)中IM消息模塊的架構(gòu)實(shí)踐
[17]?融云技術(shù)分享:全面揭秘億級(jí)IM消息的可靠投遞機(jī)制
(本文已同步發(fā)布于:http://www.52im.net/thread-4153-1-1.html)