有贊消息平臺(tái)客服系統(tǒng)技術(shù)實(shí)現(xiàn)

零七嫌、目錄#

1液样、概述####

1-1殴泰、業(yè)務(wù)場(chǎng)景
1-2芒涡、整體架構(gòu)

2、IM通道詳細(xì)分析####

2-1物延、整體實(shí)現(xiàn)
2-2宣旱、通信協(xié)議
2-3、DeviceId和NodeId生成方法
2-4叛薯、消息流轉(zhuǎn)過(guò)程
2-5浑吟、對(duì)點(diǎn)對(duì)點(diǎn)聊天的支持

3笙纤、消息推送與離線存儲(chǔ)(通常方案)####

3-1、消息持久化
3-2组力、消息在線推送與送達(dá)確認(rèn)
3-3省容、未送達(dá)消息離線拉取

4、消息推送與離線存儲(chǔ)(有贊客服系統(tǒng))####

4-1燎字、消息持久化
4-2腥椒、未讀數(shù)標(biāo)識(shí)與已讀確認(rèn)
4-3、方案優(yōu)缺點(diǎn)

一轩触、概述#

1-1寞酿、業(yè)務(wù)場(chǎng)景####

業(yè)務(wù)場(chǎng)景圖

客服系統(tǒng)家夺,為有贊店鋪和買(mǎi)家之間提供消息溝通渠道脱柱。

  • 每個(gè)有贊店鋪有自己的唯一ID標(biāo)識(shí)——kdtId;
  • 店鋪的每個(gè)買(mǎi)家將產(chǎn)生一個(gè)會(huì)話用于消息溝通,每個(gè)會(huì)話有唯一ID標(biāo)識(shí)——conversationId拉馋,會(huì)話由“店鋪+買(mǎi)家”唯一確定;
  • 一個(gè)店鋪中可以有多個(gè)客服人員榨为;
  • 每個(gè)會(huì)話中包含買(mǎi)家和一個(gè)或多個(gè)客服人員;
  • 會(huì)話中任意成員發(fā)出的消息將被會(huì)話中所有成員看到煌茴;
  • 目前消息通道包含:與有贊客服系統(tǒng)直連的店鋪客服随闺,與有贊客服系統(tǒng)直連的店鋪買(mǎi)家,通過(guò)微信公眾號(hào)聯(lián)系店鋪的微信買(mǎi)家蔓腐。

1-2矩乐、整體架構(gòu)####

有贊客服系統(tǒng)整體架構(gòu)圖

圖中:

  • 進(jìn)入系統(tǒng)的消息帶有from和to標(biāo)識(shí)。from代表發(fā)送消息的成員回论,由sender_uid唯一確定散罕;to代表接收消息的店鋪,由kdtId最終轉(zhuǎn)換為conversation_id唯一確定傀蓉;
  • 系統(tǒng)推送給IM客戶端的消息包含以下信息:消息所屬會(huì)話(conversation_id,show_nickname,show_avatar)欧漱,消息發(fā)送者信息(sender_uid,sender_nickname,sender_avatar),消息具體內(nèi)容葬燎;
  • 系統(tǒng)推送給微信的消息僅有客服給買(mǎi)家發(fā)消息的場(chǎng)景误甚,通過(guò)調(diào)用微信API完成:發(fā)送消息的店鋪公眾號(hào)(sender_openId),接收消息的微信粉絲(receiver_openId)谱净,消息具體內(nèi)容窑邦;
  • sender_uid本身包含消息發(fā)送者類型(微信粉絲、IM粉絲壕探、客服)冈钦,Logic層根據(jù)該類型進(jìn)行相應(yīng)的業(yè)務(wù)處理(對(duì)粉絲消息執(zhí)行客服調(diào)度邏輯,對(duì)客服消息執(zhí)行接待及統(tǒng)計(jì)邏輯)浩蓉;
  • recv_uid本身包含消息接收者類型(微信粉絲派继,IM粉絲宾袜,客服),Channel層根據(jù)其類型區(qū)分通道完成消息推送驾窟;

1)Channel層:通道層
負(fù)責(zé)系統(tǒng)與外部通道(socket連接庆猫,微信)的直接通信交互,消息的統(tǒng)一格式绅络、推送月培、接收。

  • IM設(shè)備連接管理恩急;
  • IM通道消息路由推送杉畜;
  • 微信通道消息格式統(tǒng)一轉(zhuǎn)換;
  • 微信通道消息推送衷恭;

2)Msg-Bus:消息總線
系統(tǒng)Channel層與Logic層的通信此叠,消息流轉(zhuǎn)的樞紐。
利用消息總線進(jìn)行系統(tǒng)解耦随珠,QoS灭袁。

3)Logic:業(yè)務(wù)層
客服系統(tǒng)具體業(yè)務(wù)實(shí)現(xiàn)。

  • 消息離線存儲(chǔ)窗看;
  • 消息業(yè)務(wù)維度拆分茸歧;
  • 客服調(diào)度業(yè)務(wù)具體實(shí)現(xiàn);

二显沈、IM通道詳細(xì)分析#

2-1软瞎、整體實(shí)現(xiàn)####

IM通道實(shí)現(xiàn)結(jié)構(gòu)

1)Connector:socket連接層
職責(zé)包括:

  • IM設(shè)備的連接管理;
  • 用戶設(shè)備的注冊(cè)登錄拉讯;
  • 用戶設(shè)備維度的消息推送涤浇;

2)Channel:通道層
職責(zé)包括:

  • 用戶維度的消息路由;
  • 消息流轉(zhuǎn)格式轉(zhuǎn)換遂唧;

3)集群結(jié)構(gòu)

  • Channel節(jié)點(diǎn)向zk注冊(cè)自己的信息芙代;
  • Connector節(jié)點(diǎn)通過(guò)zk獲取Channel節(jié)點(diǎn)的信息并與其連接,每個(gè)Connector節(jié)點(diǎn)跟集群中所有Channel節(jié)點(diǎn)建立socket連接進(jìn)行通信盖彭;
  • 外部IM設(shè)備與Connector節(jié)點(diǎn)直接建立socket連接進(jìn)行通信纹烹;
  • 每個(gè)Connector節(jié)點(diǎn)本地維護(hù)自己管理的“設(shè)備DeviceId<-->連接信息Session”的關(guān)系;
  • 全局維護(hù)"IM設(shè)備<-->Connector節(jié)點(diǎn)"關(guān)系表召边,用于記錄設(shè)備登錄情況铺呵;
  • 全局維護(hù)"用戶<-->設(shè)備連接"路由表,用于用戶維度的消息推送隧熙;

2-2片挂、通信協(xié)議####

1)外部IM設(shè)備與Connector節(jié)點(diǎn)間采用websocket協(xié)議進(jìn)行通信


編解碼過(guò)程

2)Connector節(jié)點(diǎn)與Channel節(jié)點(diǎn)之間采用私有定制協(xié)議進(jìn)行通信,具體協(xié)議格式及編解碼過(guò)程略。

2-3音念、DeviceId和NodeId生成方法####

1)DeviceId生成方法
DeviceId用于唯一標(biāo)識(shí)一個(gè)用戶登錄到系統(tǒng)的連接設(shè)備沪饺。

DeviceId結(jié)構(gòu)

使用64位(即java中的long類型)表示一個(gè)DeviceId,其生成方法參考snowflake分布式ID生成法闷愤。
[0]空缺
[1 - 3]節(jié)點(diǎn)類型

  • 000 -> 外部IM客戶端
  • 001 -> Connector節(jié)點(diǎn)
  • 010 -> Logic節(jié)點(diǎn)

[4 - 15]集群號(hào)整葡,空缺不用
[16 - 17]Device類型,目前僅有[00]一種默認(rèn)類型讥脐,留作后續(xù)擴(kuò)展
[18 - 47]時(shí)間戳
[48 - 63]16位自增ID

2)NodeId生成方法
NodeId用于標(biāo)識(shí)系統(tǒng)中一個(gè)服務(wù)節(jié)點(diǎn)遭居,作為系統(tǒng)集群節(jié)點(diǎn)內(nèi)部通信的唯一標(biāo)識(shí)。

NodeId結(jié)構(gòu)

使用64位(即java中的long類型)表示一個(gè)NodeId旬渠,其生成方法參考snowflake分布式ID生成法俱萍。
[0]空缺
[1 - 3]節(jié)點(diǎn)類型

  • 000 -> 外部IM客戶端
  • 001 -> Connector節(jié)點(diǎn)
  • 010 -> Logic節(jié)點(diǎn)

[4 - 15]集群號(hào),每個(gè)節(jié)點(diǎn)在集群中有個(gè)唯一節(jié)點(diǎn)號(hào)告丢,目前使用節(jié)點(diǎn)IP后4位
[16 - 47]32位節(jié)點(diǎn)IP信息
[48 - 63]16位節(jié)點(diǎn)Port信息

2-3枪蘑、用戶設(shè)備登錄/注冊(cè)過(guò)程&連接信息綁定####

1)幾個(gè)關(guān)鍵存儲(chǔ)

連接信息Session結(jié)構(gòu)

DeviceId<-->Session映射表(本地)

設(shè)備連接映射表

用戶設(shè)備路由表

用戶設(shè)備表DeviceInfo

2)用戶設(shè)備登錄/注冊(cè)
a、客戶端建連

  • 客戶端發(fā)起連接到Connector節(jié)點(diǎn)芋齿,Connector服務(wù)端生成連接上下文Session腥寇,并作為Attachment綁定到對(duì)應(yīng)Channel上;

b觅捆、用戶設(shè)備登錄/注冊(cè)

  • *注:userId為有贊統(tǒng)一賬戶體系,因此使用統(tǒng)一服務(wù)不做獨(dú)立存儲(chǔ)麻敌;
  • 客戶端發(fā)起用戶設(shè)備登錄請(qǐng)求栅炒,攜帶userId和deviceType信息;
  • Connector節(jié)點(diǎn)處理登錄請(qǐng)求术羔,由userId和deviceType生成hashcode(目前是直接拼接)作為查詢鍵赢赊,查詢"DeviceInfo表"對(duì)應(yīng)設(shè)備是否已登錄/注冊(cè)過(guò)。若注冊(cè)過(guò)直接拿到對(duì)應(yīng)DeviceId级历,若沒(méi)注冊(cè)過(guò)則新生成DeviceId并存入"DeviceInfo表"释移;
  • 將DeviceId填充入連接上下文Session的index字段;
  • Connector節(jié)點(diǎn)本地存儲(chǔ)"DeviceId<-->Session映射表"寥殖;
  • 全局存儲(chǔ)"設(shè)備連接映射表"和"用戶設(shè)備路由表"玩讳;

2-4、消息流轉(zhuǎn)過(guò)程####

典型交互過(guò)程圖

客戶端建連&用戶設(shè)備登錄/注冊(cè)過(guò)程嚼贡,由圖文“綠色”過(guò)程描述熏纯。
客戶端請(qǐng)求&服務(wù)端響應(yīng)過(guò)程,由圖中“粉紫色”過(guò)程描述粤策。
服務(wù)端推送消息到客戶端樟澜,由圖中“藍(lán)色”過(guò)程描述。

2-5、對(duì)點(diǎn)對(duì)點(diǎn)聊天的支持####

1)目前業(yè)務(wù)現(xiàn)狀
目前客服系統(tǒng)業(yè)務(wù)場(chǎng)景僅存在買(mǎi)家與店鋪溝通的情況秩贰,即以“買(mǎi)家+店鋪”作為會(huì)話維度(由conversationId唯一標(biāo)識(shí))霹俺。
消息接收維度均為“會(huì)話”,即會(huì)話內(nèi)某成員發(fā)送一條消息會(huì)被推送給會(huì)話內(nèi)所有其他成員毒费。
消息離線存儲(chǔ)也以會(huì)話維度進(jìn)行存儲(chǔ)及查詢吭服。
2)點(diǎn)對(duì)點(diǎn)支持
若要支持點(diǎn)對(duì)點(diǎn)聊天(客服間聊天),只需將消息接收維度擴(kuò)展為“用戶”蝗罗。
消息離線存儲(chǔ)也需單獨(dú)實(shí)現(xiàn)為“消息接收者——消息發(fā)送者”維度進(jìn)行存儲(chǔ)及查詢艇棕。

三、消息推送與離線存儲(chǔ)(通常方案)#

3-1串塑、消息持久化####

1)職責(zé)劃分
a沼琉、用戶各會(huì)話消息的存儲(chǔ)與歷史消息拉取由客戶端本地存儲(chǔ)實(shí)現(xiàn);
b桩匪、用戶各會(huì)話的未讀消息數(shù)紅點(diǎn)提示由客戶端本地累加記錄打瘪;
c、服務(wù)端保證對(duì)建連客戶端消息的實(shí)時(shí)推送傻昙;
d闺骚、服務(wù)端提供未送達(dá)消息拉取接口,對(duì)因客戶端不在線或因網(wǎng)絡(luò)異常丟失的消息妆档,當(dāng)客戶端下次建連登錄時(shí)通過(guò)調(diào)用拉取接口獲取未送達(dá)消息僻爽;
2)消息ID
a、消息量不大時(shí)贾惦,可通過(guò)集中發(fā)號(hào)器對(duì)每個(gè)會(huì)話維度的消息生成連續(xù)自增消息ID胸梆,并以“會(huì)話+消息ID”全局唯一標(biāo)識(shí)一條消息。
b须板、消息量大的情況下碰镜,集中發(fā)號(hào)器將存在性能瓶頸。此時(shí)可通過(guò)snowflake方法分布式生成全局唯一消息ID习瑰,且消息ID趨勢(shì)有序绪颖。
3)消息存儲(chǔ)維度
a、對(duì)一般點(diǎn)對(duì)點(diǎn)單聊場(chǎng)景甜奄,消息以“消息接收者”作為“查詢主鍵”進(jìn)行存儲(chǔ)與查詢柠横。
b、對(duì)特殊業(yè)務(wù)場(chǎng)景贺嫂,需明確定義會(huì)話維度滓鸠,并以“會(huì)話”作為“查詢主鍵”進(jìn)行存儲(chǔ)與查詢。

3-2第喳、消息在線推送與送達(dá)確認(rèn)####

消息在線推送過(guò)程

3-3糜俗、未送達(dá)消息離線拉取####

未送達(dá)消息離線拉取過(guò)程

由于im-server對(duì)每條消息維護(hù)“送達(dá)”狀態(tài),配合“未送達(dá)消息離線拉取接口”可保證消息100%理論上不丟失。

四悠抹、消息推送與離線存儲(chǔ)(有贊客服系統(tǒng))#

4-1珠月、消息持久化####

1)職責(zé)劃分
由于系統(tǒng)客戶端大部分為web端,并不擅長(zhǎng)做本地存儲(chǔ)楔敌,因此持久化存儲(chǔ)部分由服務(wù)端完成啤挎。
由于會(huì)話內(nèi)消息Id連續(xù)遞增,服務(wù)端對(duì)每個(gè)會(huì)話采用游標(biāo)的方式記錄最新消息位置及各用戶已讀消息位置卵凑。
a庆聘、會(huì)話消息的存儲(chǔ)與歷史消息拉取由服務(wù)端實(shí)現(xiàn);
b勺卢、用戶在各會(huì)話的未讀消息游標(biāo)由服務(wù)端存儲(chǔ)伙判,客戶端調(diào)用服務(wù)端接口更新用戶在某會(huì)話內(nèi)已讀消息游標(biāo);
c黑忱、服務(wù)端保證對(duì)建連客戶端消息的實(shí)時(shí)推送宴抚;
d、服務(wù)端提供歷史消息拉取接口甫煞,由客戶端調(diào)用分頁(yè)拉取會(huì)話內(nèi)歷史消息菇曲;
2)消息ID
通過(guò)集中發(fā)號(hào)器對(duì)每個(gè)會(huì)話維度的消息生成連續(xù)自增消息ID,并以“會(huì)話+消息ID”全局唯一標(biāo)識(shí)一條消息抚吠。
集中發(fā)號(hào)器目前使用aerospike實(shí)現(xiàn)常潮。
3)消息存儲(chǔ)維度
以會(huì)話(conversationId)作為“查詢主鍵”進(jìn)行消息存儲(chǔ)與查詢。

4-2埃跷、未讀數(shù)標(biāo)識(shí)與已讀確認(rèn)####

因?yàn)橄到y(tǒng)客戶端不進(jìn)行消息持久存儲(chǔ)蕊玷,因此系統(tǒng)將維護(hù)消息的“已讀狀態(tài)”,而非“送達(dá)狀態(tài)”弥雹。
a、系統(tǒng)為每個(gè)會(huì)話記錄當(dāng)前最大消息游標(biāo)cursor延届。
b剪勿、系統(tǒng)為會(huì)話內(nèi)每個(gè)成員記錄其在會(huì)話中當(dāng)前已讀的最大消息游標(biāo)。
c方庭、用戶客戶端登錄拉取會(huì)話列表時(shí)厕吉,后端系統(tǒng)會(huì)同時(shí)返回會(huì)話列表中每個(gè)會(huì)話的用戶未讀消息個(gè)數(shù)。
d械念、用戶客戶端在會(huì)話中讀取了消息時(shí)头朱,需給予后端系統(tǒng)反饋,后端系統(tǒng)會(huì)更新用戶在對(duì)應(yīng)會(huì)話中的已讀游標(biāo)龄减。

4-3项钮、方案優(yōu)缺點(diǎn)####

優(yōu):方案根據(jù)系統(tǒng)業(yè)務(wù)特性使用“用戶+店鋪”作為會(huì)話維度存儲(chǔ)消息,會(huì)話內(nèi)消息由集中發(fā)號(hào)器生成連續(xù)自增ID。使得系統(tǒng)實(shí)現(xiàn)復(fù)雜度降低烁巫,歷史消息分頁(yè)拉取及未讀消息數(shù)功能實(shí)現(xiàn)方便署隘。
缺:消息存儲(chǔ)維度與業(yè)務(wù)緊密關(guān)聯(lián),不便于系統(tǒng)通用擴(kuò)展亚隙。
缺:集中發(fā)號(hào)器產(chǎn)生“會(huì)話內(nèi)連續(xù)消息ID”的方式存在性能瓶頸風(fēng)險(xiǎn)磁餐。

五、模塊化后的優(yōu)化系統(tǒng)架構(gòu)#

5-1阿弃、IM推送系統(tǒng)架構(gòu)####

IM推送系統(tǒng)架構(gòu)

5-2诊霹、客服系統(tǒng)與IM推送系統(tǒng)的模塊關(guān)系####

模塊職責(zé)關(guān)系圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市渣淳,隨后出現(xiàn)的幾起案子脾还,更是在濱河造成了極大的恐慌,老刑警劉巖水由,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荠呐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡砂客,警方通過(guò)查閱死者的電腦和手機(jī)泥张,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鞠值,“玉大人媚创,你說(shuō)我怎么就攤上這事⊥瘢” “怎么了钞钙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)声离。 經(jīng)常有香客問(wèn)我芒炼,道長(zhǎng),這世上最難降的妖魔是什么术徊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任本刽,我火速辦了婚禮,結(jié)果婚禮上赠涮,老公的妹妹穿的比我還像新娘子寓。我一直安慰自己,他們只是感情好笋除,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布斜友。 她就那樣靜靜地躺著,像睡著了一般垃它。 火紅的嫁衣襯著肌膚如雪鲜屏。 梳的紋絲不亂的頭發(fā)上烹看,一...
    開(kāi)封第一講書(shū)人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音墙歪,去河邊找鬼听系。 笑死,一個(gè)胖子當(dāng)著我的面吹牛虹菲,可吹牛的內(nèi)容都是我干的靠胜。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼毕源,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浪漠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起霎褐,我...
    開(kāi)封第一講書(shū)人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤址愿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后冻璃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體响谓,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年省艳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娘纷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡跋炕,死狀恐怖赖晶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辐烂,我是刑警寧澤遏插,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站纠修,受9級(jí)特大地震影響胳嘲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扣草,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一胎围、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧德召,春花似錦、人聲如沸汽纤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蕴坪。三九已至肴掷,卻和暖如春敬锐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背呆瞻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工台夺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痴脾。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓颤介,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赞赖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滚朵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容