掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
很多業(yè)務(wù)都需要考慮消息投遞的順序性:

成都網(wǎng)絡(luò)公司-成都網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司十多年經(jīng)驗(yàn)成就非凡,專業(yè)從事做網(wǎng)站、網(wǎng)站建設(shè),成都網(wǎng)頁設(shè)計(jì),成都網(wǎng)頁制作,軟文平臺(tái),1元廣告等。十多年來已成功提供全面的成都網(wǎng)站建設(shè)方案,打造行業(yè)特色的成都網(wǎng)站建設(shè)案例,建站熱線:18982081108,我們期待您的來電!
1. 消息順序性是分布式系統(tǒng)架構(gòu)設(shè)計(jì)中非常難的問題,有什么常見優(yōu)化實(shí)踐呢?
折衷一:以客戶端或者服務(wù)端的時(shí)序?yàn)闇?zhǔn)
不管什么情況,都需要一個(gè)標(biāo)尺來衡量時(shí)序的先后順序,可以根據(jù)業(yè)務(wù)場(chǎng)景,以客戶端或者服務(wù)端的時(shí)間為準(zhǔn),例如:
畫外音:發(fā)送方只要將郵件協(xié)議里的時(shí)間調(diào)整為1970年或者2970年,就可以在接收方收到郵件后一直“置頂”或者“置底”。
折衷二:服務(wù)端生成單調(diào)遞增id作為時(shí)序依據(jù)
對(duì)于嚴(yán)格時(shí)序的業(yè)務(wù)場(chǎng)景,可以利用單點(diǎn)寫db的seq/auto_inc_id生成單調(diào)遞增的id,來保證順序性。
畫外音:這個(gè)生成id的單點(diǎn)容易成為瓶頸。
折衷三:假如業(yè)務(wù)能接受誤差不大的趨勢(shì)遞增id
消息發(fā)送、帖子發(fā)布時(shí)間、甚至秒殺時(shí)間都沒有這么精準(zhǔn)時(shí)序的要求:
所以,大部分業(yè)務(wù),長(zhǎng)時(shí)間趨勢(shì)遞增的時(shí)序就能夠滿足業(yè)務(wù)需求,非常短時(shí)間的時(shí)序誤差一定程度上能夠接受。
于是,可以始終分布式id生成算法來生成id,作為時(shí)序依據(jù)。
折衷四:利用單點(diǎn)序列化,可以保證多機(jī)相同時(shí)序
數(shù)據(jù)為了保證高可用,需要做到進(jìn)行數(shù)據(jù)冗余,同一份數(shù)據(jù)存儲(chǔ)在多個(gè)地方,怎么保證這些數(shù)據(jù)的修改消息是一致的呢?
“單點(diǎn)序列化”是可行的:
典型場(chǎng)景一:數(shù)據(jù)庫主從同步
數(shù)據(jù)庫的主從架構(gòu),上游分別發(fā)起了op1,op2,op3三個(gè)操作,主庫master來序列化所有的SQL寫操作op3,op1,op2,然后把相同的序列發(fā)送給從庫slave執(zhí)行,以保證所有數(shù)據(jù)庫數(shù)據(jù)的一致性,就是利用“單點(diǎn)序列化”這個(gè)思路。
典型場(chǎng)景二:GFS中文件的一致性
GFS(Google File System)為了保證文件的可用性,一份文件要存儲(chǔ)多份,在多個(gè)上游對(duì)同一個(gè)文件進(jìn)行寫操作時(shí),也是由一個(gè)主chunk-server先序列化寫操作,再將序列化后的操作發(fā)送給其他chunk-server,來保證冗余文件的數(shù)據(jù)一致性的。
2. 單對(duì)單聊天,怎么保證發(fā)送順序與接收順序一致呢?
單人聊天的需求,發(fā)送方A依次發(fā)出了msg1,msg2,msg3三個(gè)消息給接收方B,這三條消息能否保證顯示時(shí)序的一致性(發(fā)送與顯示的順序一致)?
方案設(shè)計(jì)思路如下:
- msg1{sender:A, seq:10, receiver:B, msg:content1}
- msg2{sender:A, seq:20, receiver:B, msg:content2}
- msg3{sender:A, seq:30, receiver:B, msg:content3}
可能存在問題是:如果接收方B先收到msg3,msg3會(huì)先展現(xiàn),后收到msg1和msg2后,會(huì)展現(xiàn)在msg3的前面。
3. 群聊消息,怎么保證各接收方收到順序一致?
群聊消息的需求,N個(gè)群友在一個(gè)群里聊,怎么保證所有群友收到的消息顯示時(shí)序一致?
方案設(shè)計(jì)思路如下:
如上圖,此時(shí)群聊的發(fā)送流程為:
這個(gè)方法能實(shí)現(xiàn),所有群友的消息展示時(shí)序相同。
缺點(diǎn)是,生成全局遞增序列號(hào)的服務(wù)很容易成為系統(tǒng)瓶頸。
4. 還有沒有進(jìn)一步的優(yōu)化方法呢?
群消息其實(shí)也不用保證全局消息序列有序,而只要保證一個(gè)群內(nèi)的消息有序即可,這樣的話,“id串行化”就成了一個(gè)很好的思路。
這個(gè)方案中,service層不再需要去一個(gè)統(tǒng)一的后端拿全局seq,而是在service連接池層面做細(xì)小的改造,保證一個(gè)群的消息落在同一個(gè)service上,這個(gè)service就可以用本地seq來序列化同一個(gè)群的所有消息,保證所有群友看到消息的時(shí)序是相同的。
此時(shí)利用本地時(shí)鐘來生成seq就湊效了,是不是很巧妙?
5. 總結(jié)
思路比結(jié)論更重要,希望大家有收獲。
【本文為專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流