手淘千牛IM即時通訊 - 星巴克訊息開放實踐
對垂直業務領域進行了解,抽象成領域模型,沉澱出通用能力和標準化體系,為後續業務賦能。 這是筆者理解的技術驅動業務。生於業務,又高於業務
筆者很榮幸可以參與到淘寶小程式的開放體系中,訊息能力的開放也是裡面很重要的一環,在雙十一前可以藉助星巴克小程式把訊息方案落地,這次做個總結。
這次星巴克訊息開放融合帶來的挑戰是:底層需要對接不同的服務體系,他們之間的協議不一致,上層業務業務又需要統一,而且整個開發迭代節奏很快。
本文主要會從垂直領域行業(包括淘系)的現狀,到IM的基本概念及流程,到方案選型分層,到核心模組的設計,到後續的規劃思考幾個方面來講述,做個自己的思考,讓大家有個全方面的理解。
文章提綱
- 行業情況(淘外和淘內),包括IM即時通訊能力和IM產品
- IM的基本概念及流程
- 方案的選型和設計
- 核心模組(訊息處理中心)能力抽象,參考Koajs的中介軟體模式設計
- 未來規劃及思考
行業情況
IM的應用場景非常廣泛,除了傳統的圖文聊天外,時下流行的線上直播聊天室、線上教育、遊戲互動等各式各樣產品中都有類似的應用場景。
在集團裡面應用場景也很廣泛, 例如淘寶聊天(BC店鋪/CC淘友),淘寶直播,即時互動場景。 對客服服務領域有阿里小蜜,都是基於即時通訊能力搭建的應用產品。
在淘系外也有很多優秀的產品
- 老羅的子彈簡訊(老羅提出的噱頭說是傳送方喜歡發語音,接受方喜歡看文字。這不是語音轉文字麼,只是自動化了)。
- 網易七魚(客服領域解決方案),其實它跟集團裡面阿里小蜜很像(機器人,快捷回覆,知識庫,呼叫中心,質檢,分流,熱門問題推薦等)
- 騰訊的QQ,微信甚至是微視等產品
調研IM行業領域,大體的產品可以分為兩個部分:第一分部為IM即時通訊能力,做訊息開放。例如網易雲信,騰訊IM雲,阿里系的百川。 例如:子彈簡訊和網易七魚是在網易雲信上面搭建的產品;QQ,微信和微視是在騰訊IM雲上搭建的產品。 第二部分IM產品。例如:上文提到的子彈簡訊,網易七魚,QQ和微信。
基本概念
IM即時通訊是不同使用者之間交流的雙通通道,如下是收發訊息的簡單模型。
我們仔細觀察上面IM產品的截圖,可以發現每個產品的表現形式會有差別。但是他們基本概念是一致,也就是說領域模型是一致的。 筆者認為兩個核心的概念是 會話
- 會話session(conversation): 它是指AB通訊之間維持的一種關係,它是訊息儲存的載體。
- 訊息message: 可以根據業務分為兩大塊訊息,會話內訊息和系統通知訊息。會話內訊息又可以分為基本訊息和自定義訊息。
基本功能
單聊
1V1 聊天,提供包括文字、圖片、語音、地理位置、檔案、自定義訊息等多種能力,除此之外還提供訊息推送功能
群聊
多人聊天服務,內建公開群、私有群、聊天室、互動直播聊天室和線上成員廣播大群五種群組形態,能夠適應各種群組需求的場景。
手淘千牛(CC/BC)即時通訊解決方案
這次星巴克訊息開放融合帶來的挑戰是:底層需要對接不同的服務體系,他們之間的協議不一致,上層業務業務又需要統一,而且整個開發迭代節奏很快。
由於他們的領域模型是一致的,那麼劃分了四個層來擴充套件。
- 通道層: 服務端不同通道來源
- 適配層: 協議對接通道,儲存
- 能力層: 對訊息進行不同的分類,對訊息能力進行原子性管理。
- 功能層(元件層): 垂直業務的通用業務元件
基於這種分層,我們可以在適配層和能力層沉澱出標準化的SDK,在功能層(元件層)可以沉澱出元件物料用於複用和擴充套件。
業務流程抽象
對於如何構建一個完整IM系統,本文把畫了一個流程圖,把關鍵流程抽象出來。流程步驟:
- 通過appkey和使用者資訊從服務端獲取會話及會話Token
- 建立Websocket連線,新增各個連線狀態的事件(連線成功,網路錯誤等)
- 在連線成功後進行業務邏輯處理。 包括髮送訊息 和 接受訊息
- 業務邏輯處理完之後斷鏈
基於這個流程可以拓展出生命週期進行業務捕獲和處理,生命週期如下:
核心模組(訊息處理中心)
Koajs中介軟體實現機制
大家對Koajs應該比較瞭解,對Node HttpServer進行了分裝,集團開源的Egg也是依賴於Koajs進行了二次分裝和中介軟體擴充套件。筆者認為Koajs最精妙的設計在於中介軟體的設計思想,抽出了Context執行上下文概念(應該是一次請求的執行上下文), 摘取了Koajs中介軟體實現的核心原始碼分享。
簡單程式碼示例
const Koa = require('koa');
const app = new Koa();
app.use(ctx => {
ctx.body = 'Hello Koa';
});
app.listen(3000);
流程介紹
初始化
startApp ---> use --> push middleware ---> listen port
一次請求發起
request --> callback --> compose ---> request ---> dispatch
重點模組解析
我們可以看到compose
是Koajs的核心模組,Koajs專門提供了一個koa-compose
的npm包。他實現了洋蔥圈的原理, 同步呼叫由外到內,非同步Promise呼叫由內到外。原理上就是遞迴原理,退出遞迴條件是在最後promise為空。
還有一個比較重要的設計是context
物件,除了在context
物件中掛載了很多常用功能及函式。我們也可以看到callback
對每次請求都會生成新的context(const ctx = this.createContext(req, res);
),這樣就有利於對請求隔離,單次請求進行中間處理。
訊息處理中心設計
訊息處理中心設計的中介軟體,也可以稱為外掛體系。借鑑了Koajs的實現。根據業務需求在context
掛載了syncIds
和msgs
屬性。外掛是對單條資料進行處理的集合。
對訊息的通道劃分,通常可以分為上行訊息和下行訊息。
- 上行訊息一般指消費者側傳送的訊息到服務端。
- 下行訊息一般指服務端訊息觸達消費者。
在使用者視角,由於為了確保訊息的安全性,流量以及協議編碼解析需要在上行訊息出口側加編碼模組,在下行訊息側入口加解碼模組。設計訊息統一流入到訊息處理中心進行處理。
SDK標準化能力輸出
基於上文概念理解,業務邏輯抽象,核心模組設計,筆者在星巴克業務中輸出了一套可以同時對接旺旺服務端和手淘的服務端的標準化訊息體系,業務邏輯在SDK下沉,減輕前臺UI表現邏輯,從而保持UI一致性,擴充套件性,提升使用者體驗。
未來展望
筆者在上文中也提到了分層,主要分為兩塊:標準化SDK
和 物件物料
。 同時在領域模型的基礎上歸納整合出標準的前端協議,從而構建出基礎能力SDK, 進而對於不同品牌構建出品牌SDK,沉澱業務元件和標準化UI。 最終可以聯合其他部門一起輸出一個集團IM的白皮書。
總結
總結是更加一層的抽象,方法論可以脫離垂直業務領域,在其他領域也可以適用。
- 垂直業務,行業內現狀分析。
- 基本概念,領域模型的建立。
- 業務流程抽象,核心模組設計。
PS:SDK的設計:事件模組,外掛模組,代理設計模式,筆者認為都是通用且必要能力。而且這些能力就可以滿足大部分業務需求