久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

既然有HTTP協(xié)議,為什么還要有RPC

 天選小丑 2022-07-29 發(fā)布于廣西

來源丨經(jīng)授權(quán)轉(zhuǎn)自 小白debug(ID:xiaobaidebug)

作者丨小白

我想起了我剛工作的時候,,第一次接觸RPC協(xié)議,,當時就很懵,我HTTP協(xié)議用的好好的,,為什么還要用RPC協(xié)議,?

于是就到網(wǎng)上去搜。

不少解釋顯得非常官方,,我相信大家在各種平臺上也都看到過,,解釋了又好像沒解釋,都在用一個我們不認識的概念去解釋另外一個我們不認識的概念,,懂的人不需要看,,不懂的人看了還是不懂。

這種看了,,又好像沒看的感覺,,云里霧里的很難受,我懂,。

為了避免大家有強烈的審丑疲勞,,今天我們來嘗試重新?lián)Q個方式講一講。

從TCP聊起

作為一個程序員,,假設(shè)我們需要在A電腦的進程發(fā)一段數(shù)據(jù)到B電腦的進程,,我們一般會在代碼里使用socket進行編程。

這時候,,我們可選項一般也就TCP和UDP二選一,。TCP可靠,UDP不可靠,。除非是馬總這種神級程序員(早期QQ大量使用UDP),,否則,只要稍微對可靠性有些要求,,普通人一般無腦選TCP就對了,。

類似下面這樣。

fd = socket(AF_INET,SOCK_STREAM,0);

其中SOCK_STREAM,,是指使用字節(jié)流傳輸數(shù)據(jù),,說白了就是TCP協(xié)議,。

在定義了socket之后,我們就可以愉快的對這個socket進行操作,,比如用bind()綁定IP端口,,用connect()發(fā)起建連。

圖片

握手建立連接流程

在連接建立之后,,我們就可以使用send()發(fā)送數(shù)據(jù),,recv()接收數(shù)據(jù)。

光這樣一個純裸的TCP連接,,就可以做到收發(fā)數(shù)據(jù)了,,那是不是就夠了?

不行,,這么用會有問題,。

使用純裸TCP會有什么問題

八股文常背,TCP是有三個特點,,面向連接,、可靠、基于字節(jié)流,。

圖片
TCP是什么

這三個特點真的概括的非常精辟,,這個八股文我們沒白背。

每個特點展開都能聊一篇文章,,而今天我們需要關(guān)注的是基于字節(jié)流這一點,。

字節(jié)流可以理解為一個雙向的通道里流淌的數(shù)據(jù),這個數(shù)據(jù)其實就是我們常說的二進制數(shù)據(jù),,簡單來說就是一大堆 01 串,。純裸TCP收發(fā)的這些 01 串之間是沒有任何邊界的,你根本不知道到哪個地方才算一條完整消息,。

圖片
01二進制字節(jié)流

正因為這個沒有任何邊界的特點,,所以當我們選擇使用TCP發(fā)送'夏洛'和'特煩惱'的時候,接收端收到的就是'夏洛特煩惱',,這時候接收端沒發(fā)區(qū)分你是想要表達'夏洛'+'特煩惱'還是'夏洛特'+'煩惱',。

圖片
消息對比

這就是所謂的粘包問題,之前也寫過一篇專門的文章聊過這個問題,。

說這個的目的是為了告訴大家,純裸TCP是不能直接拿來用的,,你需要在這個基礎(chǔ)上加入一些自定義的規(guī)則,,用于區(qū)分消息邊界

于是我們會把每條要發(fā)送的數(shù)據(jù)都包裝一下,,比如加入消息頭,,消息頭里寫清楚一個完整的包長度是多少,,根據(jù)這個長度可以繼續(xù)接收數(shù)據(jù),截取出來后它們就是我們真正要傳輸?shù)?strong>消息體,。

圖片
消息邊界長度標志

而這里頭提到的消息頭,,還可以放各種東西,比如消息體是否被壓縮過和消息體格式之類的,,只要上下游都約定好了,,互相都認就可以了,這就是所謂的協(xié)議,。

每個使用TCP的項目都可能會定義一套類似這樣的協(xié)議解析標準,,他們可能有區(qū)別,但原理都類似,。

于是基于TCP,,就衍生了非常多的協(xié)議,比如HTTP和RPC,。

HTTP和RPC

我們回過頭來看網(wǎng)絡(luò)的分層圖,。

圖片
四層網(wǎng)絡(luò)協(xié)議

TCP是傳輸層的協(xié)議,而基于TCP造出來的HTTP和各類RPC協(xié)議,,它們都只是定義了不同消息格式的應(yīng)用層協(xié)議而已,。

HTTP協(xié)議(Hyper Text Transfer Protocol),,又叫做超文本傳輸協(xié)議。我們用的比較多,,平時上網(wǎng)在瀏覽器上敲個網(wǎng)址就能訪問網(wǎng)頁,這里用到的就是HTTP協(xié)議,。

圖片
HTTP調(diào)用

RPCRemote Procedure Call),,又叫做遠程過程調(diào)用。它本身并不是一個具體的協(xié)議,,而是一種調(diào)用方式,。

舉個例子,,我們平時調(diào)用一個本地方法就像下面這樣,。

 res = localFunc(req)

如果現(xiàn)在這不是個本地方法,,而是個遠端服務(wù)器暴露出來的一個方法remoteFunc,如果我們還能像調(diào)用本地方法那樣去調(diào)用它,,這樣就可以屏蔽掉一些網(wǎng)絡(luò)細節(jié),用起來更方便,,豈不美哉,?

 res = remoteFunc(req)
圖片
RPC可以像調(diào)用本地方法那樣調(diào)用遠端方法

基于這個思路,,大佬們造出了非常多款式的RPC協(xié)議,比如比較有名的gRPC,,thrift

值得注意的是,,雖然大部分RPC協(xié)議底層使用TCP,,但實際上它們不一定非得使用TCP,,改用UDP或者HTTP,,其實也可以做到類似的功能。

圖片
基于TCP協(xié)議的HTTP和RPC協(xié)議

到這里,,我們回到文章標題的問題,。

既然有HTTP協(xié)議,為什么還要有RPC,?

其實,,TCP70年代出來的協(xié)議,而HTTP90年代才開始流行的,。而直接使用裸TCP會有問題,,可想而知,這中間這么多年有多少自定義的協(xié)議,,而這里面就有80年代出來的RPC,。

所以我們該問的不是既然有HTTP協(xié)議為什么要有RPC,而是為什么有RPC還要有HTTP協(xié)議,。

那既然有RPC了,,為什么還要有HTTP呢?

現(xiàn)在電腦上裝的各種聯(lián)網(wǎng)軟件,,比如xx管家,,xx衛(wèi)士,,它們都作為客戶端(client)需要跟服務(wù)端(server)建立連接收發(fā)消息,,此時都會用到應(yīng)用層協(xié)議,,在這種client/server (c/s)架構(gòu)下,,它們可以使用自家造的RPC協(xié)議,,因為它只管連自己公司的服務(wù)器就ok了,。

但有個軟件不同,瀏覽器(browser),,不管是chrome還是IE,它們不僅要能訪問自家公司的服務(wù)器(server),,還需要訪問其他公司的網(wǎng)站服務(wù)器,因此它們需要有個統(tǒng)一的標準,,不然大家沒法交流,。于是,HTTP就是那個時代用于統(tǒng)一 browser/server (b/s) 的協(xié)議。

也就是說在多年以前,,HTTP主要用于b/s架構(gòu),,而RPC更多用于c/s架構(gòu)。但現(xiàn)在其實已經(jīng)沒分那么清了,b/s和c/s在慢慢融合。很多軟件同時支持多端,比如某度云盤,,既要支持網(wǎng)頁版,,還要支持手機端和pc端,,如果通信協(xié)議都用HTTP的話,那服務(wù)器只用同一套就夠了,。而RPC就開始退居幕后,,一般用于公司內(nèi)部集群里,各個微服務(wù)之間的通訊,。

那這么說的話,,都用HTTP得了,還用什么RPC,?

仿佛又回到了文章開頭的樣子,,那這就要從它們之間的區(qū)別開始說起。

HTTP和RPC有什么區(qū)別

我們來看看RPC和HTTP區(qū)別比較明顯的幾個點,。

服務(wù)發(fā)現(xiàn)

首先要向某個服務(wù)器發(fā)起請求,,你得先建立連接,而建立連接的前提是,,你得知道IP地址和端口。這個找到服務(wù)對應(yīng)的IP端口的過程,,其實就是服務(wù)發(fā)現(xiàn),。

HTTP中,你知道服務(wù)的域名,,就可以通過DNS服務(wù)去解析得到它背后的IP地址,,默認80端口。

RPC的話,,就有些區(qū)別,,一般會有專門的中間服務(wù)去保存服務(wù)名和IP信息,比如consul或者etcd,,甚至是redis,。想要訪問某個服務(wù),就去這些中間服務(wù)去獲得IP和端口信息,。由于dns也是服務(wù)發(fā)現(xiàn)的一種,,所以也有基于dns去做服務(wù)發(fā)現(xiàn)的組件,比如CoreDNS,。

可以看出服務(wù)發(fā)現(xiàn)這一塊,,兩者是有些區(qū)別,但不太能分高低,。

底層連接形式

以主流的HTTP1.1協(xié)議為例,,其默認在建立底層TCP連接之后會一直保持這個連接(keep alive),之后的請求和響應(yīng)都會復用這條連接,。

RPC協(xié)議,,也跟HTTP類似,,也是通過建立TCP長鏈接進行數(shù)據(jù)交互,但不同的地方在于,,RPC協(xié)議一般還會再建個連接池,,在請求量大的時候,建立多條連接放在池內(nèi),,要發(fā)數(shù)據(jù)的時候就從池里取一條連接出來,,用完放回去,下次再復用,,可以說非常環(huán)保,。

圖片
connection_pool

由于連接池有利于提升網(wǎng)絡(luò)請求性能,所以不少編程語言的網(wǎng)絡(luò)庫里都會給HTTP加個連接池,,比如go就是這么干的,。

可以看出這一塊兩者也沒太大區(qū)別,所以也不是關(guān)鍵,。

傳輸?shù)膬?nèi)容

基于TCP傳輸?shù)南?,說到底,無非都是消息頭header和消息體body,。

header是用于標記一些特殊信息,,其中最重要的是消息體長度

body則是放我們真正需要傳輸?shù)膬?nèi)容,,而這些內(nèi)容只能是二進制01串,,畢竟計算機只認識這玩意。所以TCP傳字符串和數(shù)字都問題不大,,因為字符串可以轉(zhuǎn)成編碼再變成01串,,而數(shù)字本身也能直接轉(zhuǎn)為二進制。但結(jié)構(gòu)體呢,,我們得想個辦法將它也轉(zhuǎn)為二進制01串,,這樣的方案現(xiàn)在也有很多現(xiàn)成的,比如json,,protobuf,。

這個將結(jié)構(gòu)體轉(zhuǎn)為二進制數(shù)組的過程就叫序列化,反過來將二進制數(shù)組復原成結(jié)構(gòu)體的過程叫反序列化,。

圖片
序列化和反序列化

對于主流的HTTP1.1,,雖然它現(xiàn)在叫超文本協(xié)議,支持音頻視頻,,但HTTP設(shè)計初是用于做網(wǎng)頁文本展示的,,所以它傳的內(nèi)容以字符串為主。header和body都是如此。在body這塊,,它使用json序列化結(jié)構(gòu)體數(shù)據(jù),。

我們可以隨便截個圖直觀看下。

圖片
HTTP報文

可以看到這里面的內(nèi)容非常多的冗余,,顯得非常啰嗦,。最明顯的,像header里的那些信息,,其實如果我們約定好頭部的第幾位是content-type,,就不需要每次都真的把'content-type'這個字段都傳過來,類似的情況其實在body的json結(jié)構(gòu)里也特別明顯,。

而RPC,,因為它定制化程度更高,可以采用體積更小的protobuf或其他序列化協(xié)議去保存結(jié)構(gòu)體數(shù)據(jù),,同時也不需要像HTTP那樣考慮各種瀏覽器行為,,比如302重定向跳轉(zhuǎn)啥的。因此性能也會更好一些,,這也是在公司內(nèi)部微服務(wù)中拋棄HTTP,,選擇使用RPC的最主要原因。

圖片
HTTP原理
圖片
RPC原理

當然上面說的HTTP,,其實特指的是現(xiàn)在主流使用的HTTP1.1,,HTTP2在前者的基礎(chǔ)上做了很多改進,所以性能可能比很多RPC協(xié)議還要好,,甚至連gRPC底層都直接用的HTTP2

那么問題又來了,。

為什么既然有了HTTP2,,還要有RPC協(xié)議?

這個是由于HTTP2是2015年出來的,。那時候很多公司內(nèi)部的RPC協(xié)議都已經(jīng)跑了好些年了,,基于歷史原因,一般也沒必要去換了,。

總結(jié)

  • 純裸TCP是能收發(fā)數(shù)據(jù),,但它是個無邊界的數(shù)據(jù)流,,上層需要定義消息格式用于定義消息邊界,。于是就有了各種協(xié)議,,HTTP和各類RPC協(xié)議就是在TCP之上定義的應(yīng)用層協(xié)議,。

  • RPC本質(zhì)上不算是協(xié)議,,而是一種調(diào)用方式,,而像gRPC和thrift這樣的具體實現(xiàn),,才是協(xié)議,,它們是實現(xiàn)了RPC調(diào)用的協(xié)議,。目的是希望程序員能像調(diào)用本地方法那樣去調(diào)用遠端的服務(wù)方法,。同時RPC有很多種實現(xiàn)方式,,不一定非得基于TCP協(xié)議

  • 從發(fā)展歷史來說,,HTTP主要用于b/s架構(gòu),,而RPC更多用于c/s架構(gòu)。但現(xiàn)在其實已經(jīng)沒分那么清了,,b/s和c/s在慢慢融合,。很多軟件同時支持多端,所以對外一般用HTTP協(xié)議,,而內(nèi)部集群的微服務(wù)之間則采用RPC協(xié)議進行通訊,。

  • RPC其實比HTTP出現(xiàn)的要早,且比目前主流的HTTP1.1性能要更好,,所以大部分公司內(nèi)部都還在使用RPC,。

  • HTTP2.0HTTP1.1的基礎(chǔ)上做了優(yōu)化,性能可能比很多RPC協(xié)議都要好,,但由于是這幾年才出來的,,所以也不太可能取代掉RPC。

最后留個問題吧,,大家有沒有發(fā)現(xiàn),,不管是HTTP還是RPC,它們都有個特點,,那就是消息都是客戶端請求,,服務(wù)端響應(yīng)。客戶端沒問,,服務(wù)端肯定就不答,,這就有點僵了,但現(xiàn)實中肯定有需要下游主動發(fā)送消息給上游的場景,,比如打個網(wǎng)頁游戲,,站在那啥也不操作,怪也會主動攻擊我,,這種情況該怎么辦呢,?

參考資料

https://www.zhihu.com/question/41609070

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多