W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
解決什么業(yè)務問題
(1)端到云的實時上報需求:58速運司機端GPS實時上報
(2)云到端的實時推送需求:58速運司機訂單實時推送
(3)端到端的聊天消息需求:用戶、商戶、客服之間的聊天溝通
難點:
(1)APP無線環(huán)境下消息可達性
(2)通用性,平臺實現(xiàn)盡量與業(yè)務解耦
【端到云:http輪詢上報GPS消息】
方案一:直接通過業(yè)務線web-server寫DB
方案二:通用web-server層調(diào)用業(yè)務服務層寫DB
潛在不足:
(1)http短連接代價高(反復創(chuàng)建與銷毀連接)
(2)web-server層吞吐量較低(每秒處理千級別請求)
【云到端:通過第三方push或者推送服務】
方案一:通過APNs或者米推等第三方推送
方案二:通過自己搭建mqtt服務推送
潛在不足:
(1)第三方可達性與實時性無法保證,第三方會進行推送限速
(2)mqtt可用性是個問題
業(yè)務的分析與抽象:司機、用戶、商家、客服均為“在線”業(yè)務
【端到云的優(yōu)化】
傳統(tǒng)方案潛在的問題:http輪詢效率不高,web-server性能有限
優(yōu)化TIPS:消息平臺使用tcp長連接(如上圖)
潛在的問題:消息平臺與業(yè)務線app-server耦合,需要switch case業(yè)務線類型來分發(fā)投遞消息,新增業(yè)務線需要新增RPC調(diào)用(如上圖)
優(yōu)化TIPS:使用消息總線msg-queue解耦(如下圖)
【云到端的優(yōu)化】
潛在的問題:可用性問題與第三方限速
優(yōu)化TIPS:自己提供消息平臺集群,提供RPC接口,實現(xiàn)“云到端”的消息通道
潛在的問題:不少司機推送訂單無回復,搶單率比預期的低
優(yōu)化TIPS:引入狀態(tài)實時存儲,只有“在線”狀態(tài)的用戶才推送消息
【端到端的優(yōu)化】
如果業(yè)務無關(guān),則直接通過tcp通道投遞;如果業(yè)務相關(guān),發(fā)送方先來一個“端到云”的投遞(通過mq),業(yè)務服務器處理再反向來一個“云到端”的投遞(RPC)給接收方。
潛在問題:如果接收方不在線怎么辦
優(yōu)化TIPS:增加DB存儲離線消息
潛在的問題:無線環(huán)境下經(jīng)常網(wǎng)絡不穩(wěn)(例如進出電梯斷網(wǎng)),消息經(jīng)常丟失
優(yōu)化TIPS:消息平臺收到消息先落地數(shù)據(jù)庫,接收方收到后應用層ACK再刪除,以保證不丟失
如上圖(本文最重要的2張圖之一),整個消息投遞流程為:
(1)發(fā)送發(fā)將消息發(fā)給消息平臺
(2)消息平臺先將消息落地DB
(3)消息平臺回復發(fā)送方消息發(fā)送成功(此時和接收方是否接到無關(guān))
(3)與此同時,并行的把消息投遞給接收方(如果不在線就存離線了)
(4)接收方應用層ACK表示收到了消息
(5)消息平臺將消息刪除
(6)告之接收方ACK已經(jīng)成功處理
可以看到,是使用“應用層ACK來解決消息可達性問題的”
潛在問題:發(fā)送方?jīng)]有收到第3步驟中的消息平臺回復怎么辦?
優(yōu)化TIPS:發(fā)送方重發(fā)(服務器無狀態(tài))
潛在問題:接收方收到重發(fā)的冗余消息怎么辦?
優(yōu)化TIPS:接收方去重(可以做到服務端完全無狀態(tài),只需要簡單投遞消息即可)
整個系統(tǒng)的分層架構(gòu)如上圖(本文最重要的2張圖之二),整個消息平臺系統(tǒng)由:
(1)消息平臺在APP里的msg-sdk,向APP提供帥氣的接口
(2)msg-gate,整個消息平臺的tcp接入門戶,保持tcp長連接,初步攻防,加解密,壓縮解壓縮
(3)msg-logic,整個消息平臺邏輯處理的部分
(4)redis,高可用redis集群存儲用戶在線狀態(tài)online/offline,以及用戶在哪一臺msg-gate接入(如果在線)
(5)DB,存儲離線消息
非消息平臺的幾個業(yè)務部分:
(1)APP:業(yè)務方APP,可以有多個,通過msg-sdk來接入消息平臺
(2)mq:消息平臺通過mq來給業(yè)務方服務器發(fā)“端到云”的消息
(3)app-server:業(yè)務方后端,可以有多個,通過mq接收“端到云”的消息,通過RPC發(fā)送“云到端”的消息
【對外提供的接口說明】
消息平臺對業(yè)務方提供的接口是很少很通用的接口。
msg-sdk對APP提供的核心接口有:
(1)login:接入消息平臺
(2)logout:登出消息平臺
(3)c2s:發(fā)送client to server“端到云”的消息
(4)c2c:發(fā)送client to client“端到端”的消息
(5)get-offline-msg:拉取離線消息
(6)on-msg-recieved:收到消息的callback回調(diào)接口
消息平臺對app-server提供的核心接口有:
(1)s2c:發(fā)送server to client“云到端”的消息
其他業(yè)務方不需要關(guān)注,是msg-sdk與消息平臺之間的內(nèi)部接口有:
(1)keepalive:用于msg-sdk與消息平臺的連接保持(對業(yè)務方透明)
(2)c2c-ack:用戶c2c接口的應用層ack接口(對業(yè)務方透明)
【如何實現(xiàn)跨帳號體系的聊天】
既然是通用的消息平臺,如何實現(xiàn)跨帳號體系的消息發(fā)送呢(即如何實現(xiàn)qq與旺旺的聊天)?
解決方案:不再使用uid作為整個系統(tǒng)運行的key,而使用domain+uid,或者appid+uid來作為整個系統(tǒng)運行的key
潛在耦合點:這樣的話,login接口的邏輯處理,消息平臺需要switch case (domain或者appid)來進行不同的登錄驗證,與業(yè)務有一定的耦合,不過新增帳號體系的頻度很低,遠比新增消息類型低
【協(xié)議的擴展性設(shè)計】
APP本質(zhì)是cs架構(gòu),一旦放出去的版本就很難收回來,其兼容系要求遠比bs架構(gòu)難,如何做到新增功能的同時,還能方便的兼容歷史舊版APP呢?
(1)如何方便的增加接口?
解決方案:協(xié)議使用定長包頭 + 變長包體,使用命令號cmd來擴展新接口【這個變化對業(yè)務層是透明的,是msg-sdk與消息平臺之間的事情】
(2)對于同一個接口,能否增加參數(shù),而不影響舊版本的APP?
解決方案:使用可擴展的序列化協(xié)議,例如protobuffer【protobuffer這個東西也對業(yè)務線透明】
(3)對于業(yè)務方,有很多種類的消息類型,有很多復雜的業(yè)務需求,如何保證業(yè)務擴展性的同時,又不會增加消息平臺的復雜性,并對舊版本APP兼容?
例如業(yè)務線可能有這樣的潛在需求:
a)推送一個運營消息
b)推送消息內(nèi)容支持字體、字號、加粗、顏色
c)推送消息支持圖片
d)業(yè)務支持“窗口震動”,以及“對方正在輸入......”等需求
解決方案:使用可擴展的消息體協(xié)議(對消息平臺透明),例如xml/json來支持可擴展的多樣消息類型,并對舊版本APP兼容
<msg>抱歉,主持人提醒時間已到,分布式架構(gòu)擴展性、負載均衡性、可用性、一致性的問題線下和大家分享,先放一個分布式架構(gòu)圖吧:
(1)“端到云”消息投遞:TCP消息通道,消息總線業(yè)務解耦
(2)“云到端”消息投遞:提供RPC接口,引入狀態(tài)存儲
(3)“端到端”消息投遞步驟如下圖:
d)接收方消息去重
(5)可擴展協(xié)議設(shè)計
a)定長包頭,變長包體,隨時增加接口c)可擴展消息協(xié)議,隨時增加類型
(6)支持跨帳號體系聊天(多個域):使用domain(或者appid)+uid作為綜合key
(7)分層架構(gòu)如下圖
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: