鏈接:https://www.zhihu.com/question/41609070/answer/191965937 這個(gè)回答里恰巧講了一些rpc通信協(xié)議的細(xì)節(jié),但是強(qiáng)調(diào)一遍通信協(xié)議不是rpc最重要的部分,不要被這個(gè)回答帶偏了。如果要了解rpc請更多的去了解服務(wù)治理(soa)的一些基本策略,推薦去看看dubbo的文檔。 這個(gè)問題其實(shí)是有理解誤區(qū)的,首先 http 和 rpc 并不是一個(gè)并行概念。 rpc是遠(yuǎn)端過程調(diào)用,其調(diào)用協(xié)議通常包含傳輸協(xié)議和序列化協(xié)議。 傳輸協(xié)議包含: 如著名的 [gRPC](grpc / grpc.io) 使用的 http2 協(xié)議,也有如dubbo一類的自定義報(bào)文的tcp協(xié)議。 序列化協(xié)議包含: 如基于文本編碼的 xml json,也有二進(jìn)制編碼的 protobuf hessian等。 因此我理解的你想問的問題應(yīng)該是:為什么要使用自定義 tcp 協(xié)議的 rpc 做后端進(jìn)程通信? 要解決這個(gè)問題就應(yīng)該搞清楚 http 使用的 tcp 協(xié)議,和我們自定義的 tcp 協(xié)議在報(bào)文上的區(qū)別。 首先要否認(rèn)一點(diǎn) http 協(xié)議相較于自定義tcp報(bào)文協(xié)議,增加的開銷在于連接的建立與斷開。http協(xié)議是支持連接池復(fù)用的,也就是建立一定數(shù)量的連接不斷開,并不會(huì)頻繁的創(chuàng)建和銷毀連接。二一要說的是http也可以使用protobuf這種二進(jìn)制編碼協(xié)議對內(nèi)容進(jìn)行編碼,因此二者最大的區(qū)別還是在傳輸協(xié)議上。 通用定義的http1.1協(xié)議的tcp報(bào)文包含太多廢信息,一個(gè)POST協(xié)議的格式大致如下
即使編碼協(xié)議也就是body是使用二進(jìn)制編碼協(xié)議,報(bào)文元數(shù)據(jù)也就是header頭的鍵值對卻用了文本編碼,非常占字節(jié)數(shù)。如上圖所使用的報(bào)文中有效字節(jié)數(shù)僅僅占約 30%,也就是70%的時(shí)間用于傳輸元數(shù)據(jù)廢編碼。當(dāng)然實(shí)際情況下報(bào)文內(nèi)容可能會(huì)比這個(gè)長,但是報(bào)頭所占的比例也是非??捎^的。 那么假如我們使用自定義tcp協(xié)議的報(bào)文如下 報(bào)頭占用的字節(jié)數(shù)也就只有16個(gè)byte,極大地精簡了傳輸內(nèi)容。 這也就是為什么后端進(jìn)程間通常會(huì)采用自定義tcp協(xié)議的rpc來進(jìn)行通信的原因。 -- 分割線 2017.08.03 -- 可能回答里面沒有描述清楚,這個(gè)回答僅僅是用來糾正victory的回答的。所謂的效率優(yōu)勢是針對http1.1協(xié)議來講的,http2.0協(xié)議已經(jīng)優(yōu)化編碼效率問題,像grpc這種rpc庫使用的就是http2.0協(xié)議。這么來說吧http容器的性能測試單位通常是kqps,自定義tpc協(xié)議則通常是以10kqps到100kqps為基準(zhǔn) 簡單來說成熟的rpc庫相對http容器,更多的是封裝了“服務(wù)發(fā)現(xiàn)”,"負(fù)載均衡",“熔斷降級(jí)”一類面向服務(wù)的高級(jí)特性??梢赃@么理解,rpc框架是面向服務(wù)的更高級(jí)的封裝。如果把一個(gè)http servlet容器上封裝一層服務(wù)發(fā)現(xiàn)和函數(shù)代理調(diào)用,那它就已經(jīng)可以做一個(gè)rpc框架了。 所以為什么要用rpc調(diào)用? 因?yàn)榱己玫膔pc調(diào)用是面向服務(wù)的封裝,針對服務(wù)的可用性和效率等都做了優(yōu)化。單純使用http調(diào)用則缺少了這些特性。 |
|