HTTP和RPC
什么是HTTP
HTTP協議(Hyper Text Transfer Protocol),又叫做超文本傳輸協議。平時上網在瀏覽器上敲個網址就能訪問網頁,這里用到的就是HTTP協議。
什么是RPC
RPC(Remote Procedure Call),又叫做遠程過程調用。它并不是一個具體的協議,而是一種調用方式。
像之前的單體時代,我們的 service 調用就是自己實現的方法,是本地進程內的調用。
public User getUserById(Long id) {
return userDao.getUserById(id); // 這叫本地調用
}
現在都是微服務了,根據業務模塊做了不同的拆分,像用戶的服務不用我這個小組負責,我這小組只要寫訂單服務就行了。
但是我們服務需要用到用戶的信息,于是我們需要調用用戶小組的服務,于是代碼變成了以下這種
public User getUserById(Long id) {
return userConsumer.getUserById(id); // 遠程調用
}
我們像調用本地方法那樣去調用它,屏蔽掉一些網絡細節,這樣用起來豈不是很方便。
值得注意的是,雖然大部分RPC協議底層使用TCP,但實際上它們不一定非得使用TCP,改用UDP或者HTTP,其實也可以做到類似的功能。
既然有RPC了,為什么還要有HTTP?
RPC 調用使用的場景更多的公司內部的多個服務之間的通信。
服務的拆分獨立部署,那服務間的調用就必然需要網絡通信,用 Http的方式 調用當然可行,但是比較麻煩。
想要服務被拆分了但是使用起來還是和之前本地調用一樣方便,所以就出現了 RPC 框架,來屏蔽這些底層調用細節,使得我們編碼上還是和之前本地調用相差不多。
HTTP 協議比較的冗余,RPC 都是內部調用所以不需要太考慮通用性,只要公司內部保持格式統一即可。
HTTP和RPC有什么區別
我們來看看RPC和HTTP區別比較明顯的幾個點。
服務發現
首先要向某個服務器發起請求,你得先建立連接,而建立連接的前提是,你得知道IP地址和端口。這個找到服務對應的IP端口的過程,其實就是服務發現。
在HTTP中,你知道服務的域名,就可以通過DNS服務去解析得到它背后的IP地址。
而RPC的話,就有些區別,一般會有專門的中間服務去保存服務名和IP信息,比如consul。想要訪問某個服務,就去這些中間服務去獲得IP和端口信息。
底層連接形式
以主流的HTTP1.1協議為例,其默認在建立底層TCP連接之后會一直保持這個連接(keep alive),之后的請求和響應都會復用這條連接。
RPC,也跟HTTP類似,也是通過建立TCP長鏈接進行數據交互,但不同的地方在于,RPC協議一般還會再建個連接池,在請求量大的時候,建立多條連接放在池內,要發數據的時候就從池里取一條連接出來,用完放回去,下次再復用,可以說非常環保。
由于連接池有利于提升網絡請求性能,所以不少編程語言的網絡庫里都會給HTTP加個連接池,比如go就是這么干的。這一塊兩者也沒太大區別。
傳輸的內容
基于TCP傳輸的消息:header是用于標記一些特殊信息、body則是放我們真正需要傳輸的內容。
可以看到像header里的很多信息,其實如果我們約定好之后,就不用每次都傳輸了,比如"content-type"這個字段。
RPC,因為它定制化程度更高,可以采用體積更小的protobuf或其他序列化協議去保存結構體數據,同時也不需要像HTTP那樣考慮各種瀏覽器行為,比如302重定向跳轉什么的。因此性能也會更好一些。
HTTP原理
RPC原理