這篇文章主要介紹了RPC消息協(xié)議設(shè)計(jì)原理是什么的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇RPC消息協(xié)議設(shè)計(jì)原理是什么文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),港北企業(yè)網(wǎng)站建設(shè),港北品牌網(wǎng)站建設(shè),網(wǎng)站定制,港北網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,港北網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。消息邊界
RPC 需要在一條 TCP 鏈接上進(jìn)行多次消息傳遞。在連續(xù)的兩條消息之間必須有明確的分割規(guī)則,以便接收端可以將消息分割開(kāi)來(lái),這里的接收端可以是 RPC 服務(wù)器接收請(qǐng)求,也可以是 RPC 客戶端接收響應(yīng)。
基于 TCP 鏈接之上的單條消息如果過(guò)大,就會(huì)被網(wǎng)絡(luò)協(xié)議棧拆分為多個(gè)數(shù)據(jù)包進(jìn)行傳送。如果消息過(guò)小,網(wǎng)絡(luò)協(xié)議棧可能會(huì)將多個(gè)消息組合成一個(gè)數(shù)據(jù)包進(jìn)行發(fā)送。對(duì)于接收端來(lái)說(shuō)它看到的只是一串串的字節(jié)數(shù)組,如果沒(méi)有明確的消息邊界規(guī)則,接收端是無(wú)從知道這一串字節(jié)數(shù)組究竟是包含多條消息還是只是某條消息的一部分。
比較常用的兩種分割方式是特殊分割符法和長(zhǎng)度前綴法。
消息發(fā)送端在每條消息的末尾追加一個(gè)特殊的分割符,并且保證消息中間的數(shù)據(jù)不能包含特殊分割符。比如最為常見(jiàn)的分割符是 。當(dāng)接收端遍歷字節(jié)數(shù)組時(shí)發(fā)現(xiàn)了 ,就立即可以斷定 之前的字節(jié)數(shù)組是一條完整的消息,可以傳遞到上層邏輯繼續(xù)進(jìn)行處理。HTTP 和 Redis 協(xié)議就大量使用了 分割符。此種消息一般要求消息體的內(nèi)容是文本消息。
消息發(fā)送端在每條消息的開(kāi)頭增加一個(gè) 4 字節(jié)長(zhǎng)度的整數(shù)值,標(biāo)記消息體的長(zhǎng)度。這樣消息接受者首先讀取到長(zhǎng)度信息,然后再讀取相應(yīng)長(zhǎng)度的字節(jié)數(shù)組就可以將一個(gè)完整的消息分離出來(lái)。此種消息比較常用于二進(jìn)制消息。
基于特殊分割符法的優(yōu)點(diǎn)在于消息的可讀性比較強(qiáng),可以直接看到消息的文本內(nèi)容,缺點(diǎn)是不適合傳遞二進(jìn)制消息,因?yàn)槎M(jìn)制的字節(jié)數(shù)組里面很容易就冒出連續(xù)的兩個(gè)字節(jié)內(nèi)容正好就是 分割符的 ascii 值。如果需要傳遞的話,一般是對(duì)二進(jìn)制進(jìn)行 base64 編碼轉(zhuǎn)變成普通文本消息再進(jìn)行傳送。
基于長(zhǎng)度前綴法的優(yōu)點(diǎn)和缺點(diǎn)同特殊分割符法正好是相反的。長(zhǎng)度前綴法因?yàn)檫m用于二進(jìn)制協(xié)議,所以可讀性很差。但是對(duì)傳遞的內(nèi)容本身沒(méi)有特殊限制,文本和內(nèi)容皆可以傳輸,不需要進(jìn)行特殊處理。HTTP 協(xié)議的 Content-Length 頭信息用來(lái)標(biāo)記消息體的長(zhǎng)度,這個(gè)也可以看成是長(zhǎng)度前綴法的一種應(yīng)用。
HTTP 協(xié)議是一種基于特殊分割符和長(zhǎng)度前綴法的混合型協(xié)議。比如 HTTP 的消息頭采用的是純文本外加 分割符,而消息體則是通過(guò)消息頭中的 Content-Type 的值來(lái)決定長(zhǎng)度。HTTP 協(xié)議雖然被稱之為文本傳輸協(xié)議,但是也可以在消息體中傳輸二進(jìn)制數(shù)據(jù)數(shù)據(jù)的,例如音視頻圖像,所以 HTTP 協(xié)議被稱之為「超文本」傳輸協(xié)議。
消息的結(jié)構(gòu)
每條消息都有它包含的語(yǔ)義結(jié)構(gòu)信息,有些消息協(xié)議的結(jié)構(gòu)信息是顯式的,還有些是隱式的。比如 json 消息,它的結(jié)構(gòu)就可以直接通過(guò)它的內(nèi)容體現(xiàn)出來(lái),所以它是一種顯式結(jié)構(gòu)的消息協(xié)議。
json 這種直觀的消息協(xié)議的可讀性非常棒,但是它的缺點(diǎn)也很明顯,有太多的冗余信息。比如每個(gè)字符串都使用雙引號(hào)來(lái)界定邊界,key/value 之間必須有冒號(hào)分割,對(duì)象之間必須使用大括號(hào)分割等等。這些還只是冗余的小頭,大的冗余還在于連續(xù)的多條 json 消息即使結(jié)構(gòu)完全一樣,僅僅只是 value 的值不一樣,也需要發(fā)送同樣的 key 字符串信息。
消息的結(jié)構(gòu)在同一條消息通道上是可以復(fù)用的,比如在建立鏈接的開(kāi)始 RPC 客戶端和服務(wù)器之間先交流協(xié)商一下消息的結(jié)構(gòu),后續(xù)發(fā)送消息時(shí)只需要發(fā)送一系列消息的 value 值,接收端會(huì)自動(dòng)將 value 值和相應(yīng)位置的 key 關(guān)聯(lián)起來(lái),形成一個(gè)完成的結(jié)構(gòu)消息。在 Hadoop 系統(tǒng)中廣泛使用的 avro 消息協(xié)議就是通過(guò)這種方式實(shí)現(xiàn)的,在 RPC 鏈接建立之處就開(kāi)始交流消息的結(jié)構(gòu),后續(xù)消息的傳遞就可以節(jié)省很多流量。
消息的隱式結(jié)構(gòu)一般是指那些結(jié)構(gòu)信息由代碼來(lái)約定的消息協(xié)議,在 RPC 交互的消息數(shù)據(jù)中只是純粹的二進(jìn)制數(shù)據(jù),由代碼來(lái)確定相應(yīng)位置的二進(jìn)制是屬于哪個(gè)字段。比如下面的這段代碼
如果純粹看消息內(nèi)容是無(wú)法知道節(jié)點(diǎn)消息內(nèi)容中的哪些字節(jié)的含義,它的消息結(jié)構(gòu)是通過(guò)代碼的結(jié)構(gòu)順序來(lái)確定的。這種隱式的消息的優(yōu)點(diǎn)就在于節(jié)省傳輸流量,它完全不需要傳輸結(jié)構(gòu)信息。
消息壓縮
如果消息的內(nèi)容太大,就要考慮對(duì)消息進(jìn)行壓縮處理,這可以減輕網(wǎng)絡(luò)帶寬壓力。但是這同時(shí)也會(huì)加重 CPU 的負(fù)擔(dān),因?yàn)閴嚎s算法是 CPU 計(jì)算密集型操作,會(huì)導(dǎo)致操作系統(tǒng)的負(fù)載加重。所以,最終是否進(jìn)行消息壓縮,一定要根據(jù)業(yè)務(wù)情況加以權(quán)衡。
如果確定壓縮,那么在選擇壓縮算法包時(shí),務(wù)必挑選那些底層用 C 語(yǔ)言實(shí)現(xiàn)的算法庫(kù),因?yàn)?Python 的字節(jié)碼執(zhí)行起來(lái)太慢了。比較流行的消息壓縮算法有 Google 的 snappy 算法,它的運(yùn)行性能非常好,壓縮比例雖然不是最優(yōu)的,但是離最優(yōu)的差距已經(jīng)不是很大。阿里的 SOFA RPC 就使用了 snappy 作為協(xié)議層壓縮算法。
流量的極致優(yōu)化
開(kāi)源的流行 RPC 消息協(xié)議往往對(duì)消息流量?jī)?yōu)化到了極致,它們通過(guò)這種方式來(lái)打動(dòng)用戶,吸引用戶來(lái)使用它們。比如對(duì)于一個(gè)整形數(shù)字,一般使用 4 個(gè)字節(jié)來(lái)表示一個(gè)整數(shù)值。
但是經(jīng)過(guò)研究發(fā)現(xiàn),消息傳遞中大部分使用的整數(shù)值都是很小的非負(fù)整數(shù),如果全部使用 4 個(gè)字節(jié)來(lái)表示一個(gè)整數(shù)會(huì)很浪費(fèi)。所以就發(fā)明了一個(gè)類型叫變長(zhǎng)整數(shù)varint。數(shù)值非常小時(shí),只需要使用一個(gè)字節(jié)來(lái)存儲(chǔ),數(shù)值稍微大一點(diǎn)可以使用 2 個(gè)字節(jié),再大一點(diǎn)就是 3 個(gè)字節(jié),它還可以超過(guò) 4 個(gè)字節(jié)用來(lái)表達(dá)長(zhǎng)整形數(shù)字。
其原理也很簡(jiǎn)單,就是保留每個(gè)字節(jié)的最高位的 bit 來(lái)標(biāo)識(shí)是否后面還有字節(jié),1 表示還有字節(jié)需要繼續(xù)讀,0 表示到讀到當(dāng)前字節(jié)就結(jié)束。
那如果是負(fù)數(shù)該怎么辦呢?-1 的 16 進(jìn)制數(shù)是 0xFFFFFFFF,如果要按照這個(gè)編碼那豈不是要 6 個(gè)字節(jié)才能存的下。-1 也是非常常見(jiàn)的整數(shù)啊。
于是 zigzag 編碼來(lái)了,專門用來(lái)解決負(fù)數(shù)問(wèn)題。zigzag 編碼將整數(shù)范圍一一映射到自然數(shù)范圍,然后再進(jìn)行 varint 編碼。
zigzag 將負(fù)數(shù)編碼成正奇數(shù),正數(shù)編碼成偶數(shù)。解碼的時(shí)候遇到偶數(shù)直接除 2 就是原值,遇到奇數(shù)就加 1 除 2 再取負(fù)就是原值。
關(guān)于“RPC消息協(xié)議設(shè)計(jì)原理是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“RPC消息協(xié)議設(shè)計(jì)原理是什么”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道。
網(wǎng)站標(biāo)題:RPC消息協(xié)議設(shè)計(jì)原理是什么-創(chuàng)新互聯(lián)
地址分享:http://www.rwnh.cn/article30/ceghpo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、虛擬主機(jī)、動(dòng)態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容