1. 程式人生 > >有http 請求,為什麼還要用rpc呼叫?

有http 請求,為什麼還要用rpc呼叫?

作者:手不要亂摸 連結:https://www.zhihu.com/question/41609070/answer/191965937 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。  

這個回答裡恰巧講了一些rpc通訊協議的細節,但是強調一遍通訊協議不是rpc最重要的部分,不要被這個回答帶偏了。如果要了解rpc請更多的去了解服務治理(soa)的一些基本策略,推薦去看看dubbo的文件。

這個問題其實是有理解誤區的,首先 http 和 rpc 並不是一個並行概念。

rpc是遠端過程呼叫,其呼叫協議通常包含傳輸協議和編碼協議。

傳輸協議包含: 如著名的 [gRPC](grpc / grpc.io

) 使用的 http2 協議,也有如dubbo一類的自定義報文的tcp協議。

編碼協議包含: 如基於文字編碼的 xml json,也有二進位制編碼的 protobuf binpack 等。

因此我理解的你想問的問題應該是:為什麼要使用自定義 tcp 協議的 rpc 做後端程序通訊?

要解決這個問題就應該搞清楚 http 使用的 tcp 協議,和我們自定義的 tcp 協議在報文上的區別。

首先要否認一點 http 協議相較於自定義tcp報文協議,增加的開銷在於連線的建立與斷開。http協議是支援連線池複用的,也就是建立一定數量的連線不斷開,並不會頻繁的建立和銷燬連線。二一要說的是http也可以使用protobuf這種二進位制編碼協議對內容進行編碼,因此二者最大的區別還是在傳輸協議上。

通用定義的http1.1協議的tcp報文包含太多廢資訊,一個POST協議的格式大致如下

HTTP/1.0 200 OK 
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84

<html>
  <body>Hello World</body>
</html>

即使編碼協議也就是body是使用二進位制編碼協議,報文元資料也就是header頭的鍵值對卻用了文字編碼,非常佔位元組數。如上圖所使用的報文中有效位元組數僅僅佔約 30%,也就是70%的時間用於傳輸元資料廢編碼。當然實際情況下報文內容可能會比這個長,但是報頭所佔的比例也是非常可觀的。

那麼假如我們使用自定義tcp協議的報文如下

&amp;lt;img data-rawheight=&quot;188&quot; src=&quot;https://pic3.zhimg.com/50/v2-89c905b0806577471aa7789a25ac0d44_hd.jpg&quot; data-rawwidth=&quot;1220&quot; class=&quot;origin_image zh-lightbox-thumb&quot; width=&quot;1220&quot; data-original=&quot;https://pic3.zhimg.com/v2-89c905b0806577471aa7789a25ac0d44_r.jpg&quot;&amp;gt;

報頭佔用的位元組數也就只有16個byte,極大地精簡了傳輸內容。

這也就是為什麼後端程序間通常會採用自定義tcp協議的rpc來進行通訊的原因。

-- 分割線 2017.08.03 --

可能回答裡面沒有描述清楚,這個回答僅僅是用來糾正victory的回答的。所謂的效率優勢是針對http1.1協議來講的,http2.0協議已經優化編碼效率問題,像grpc這種rpc庫使用的就是http2.0協議。這麼來說吧http容器的效能測試單位通常是kqps,自定義tpc協議則通常是以10kqps到100kqps為基準

簡單來說成熟的rpc庫相對http容器,跟多的是封裝了“服務發現”,"錯誤重試"一類面向服務的高階特性。可以這麼理解,rpc框架是面向服務的更高階的封裝。如果把一個http server容器上封裝一層服務發現和函式代理呼叫,那它就已經可以做一個rpc框架了。

所以為什麼要用rpc呼叫?

因為良好的rpc呼叫是面向服務的封裝,針對服務的可用性和效率等都做了優化。單純使用http呼叫則缺少了這些特性。