HTTP,TCP, socket,RPC 與gRPC


TCP/HTTP與socket

首先回顧下計算機網絡的五(七)層協議:物理層、數據鏈路層、網絡層、傳輸層、(會話層、表示層)和應用層。那么從協議上來講:

  • TCP是傳輸層協議,主要解決數據如何在網絡中傳輸
  • HTTP 是應用層協議,主要解決如何包裝數據(文本信息),是建立在tcp協議之上的應用。TCP協議是以二進制數據流的形式解決傳輸層的事兒,但對上層的應用開發極不友好,所以面向應用層的開發又產生了HTTP協議。
  •  

     

而socket 是針對TCP或UDP的具體接口實現,提供了在傳輸層進行網絡編程的方法。

以上內容我們應該都聽說的比較多了,下面主要來談一談RPC。

什么是RPC?

RPC(Remote Procedure Call)是遠程過程調用,比如說現在有兩台服務器A, B,一個在A服務器上的應用想要調用B服務器上的應用提供的某個,由於不在兩個方法不在一個內存空間,不能直接調用,需要通過網絡表達調用的語義和傳達調用的數據。常存在於分布式系統中。

為何有http協議之后,還要RPC調用?

 

 

RPC跟HTTP不是對立面,RPC中可以使用HTTP作為通訊協議。RPC是一種設計、實現框架,通訊協議只是其中一部分。

RPC的本質是提供了一種輕量無感知的跨進程通信的方式,在分布式機器上調用其他方法與本地調用無異(遠程調用的過程是透明的,你並不知道這個調用的方法是部署在哪里,通過PRC能夠解耦服務)。RPC是根據語言的API來定義的,而不是基於網絡的應用來定義的,調用更方便,協議私密更安全、內容更小效率更高。

http接口是在接口不多、系統與系統交互較少的情況下,解決信息孤島初期常使用的一種通信手段;優點就是簡單、直接、開發方便。利用現成的http協議 進行傳輸。但是如果是一個大型的網站,內部子系統較多、接口非常多的情況下,RPC框架的好處就顯示出來了,首先(基於TCP協議的情況下)就是長鏈接,不必每次通信都要像http 一樣去3次握手什么的,減少了網絡開銷;其次就是RPC框架一般都有注冊中心,有豐富的監控管理;發布、下線接口、動態擴展等,對調用方來說是無感知、統 一化的操作。第三個來說就是安全性。最后就是最近流行的服務化架構、服務化治理,RPC框架是一個強力的支撐。

鏈接:https://www.zhihu.com/question/41609070/answer/191965937

為什么要使用自定義 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協議的報文如下

報頭占用的字節數也就只有16個byte,極大地精簡了傳輸內容。

這也就是為什么后端進程間通常會采用自定義tcp協議的rpc來進行通信的原因。

所謂的效率優勢是針對http1.1協議來講的,http2.0協議已經優化編碼效率問題,像grpc這種rpc庫使用的就是http2.0協議。這么來說吧http容器的性能測試單位通常是kqps,自定義tpc協議則通常是以10kqps到100kqps為基准

簡單來說成熟的rpc庫相對http容器,更多的是封裝了“服務發現”,"負載均衡",“熔斷降級”一類面向服務的高級特性。可以這么理解,rpc框架是面向服務的更高級的封裝。如果把一個http servlet容器上封裝一層服務發現和函數代理調用,那它就已經可以做一個rpc框架了。

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

RPC 中要解決的問題:

  • 建立通信:在客戶端與服務端建立起數據傳輸通道,大都是TCP連接(gRPC使用了HTTP2)。
  • 尋址:A服務器上的應用需要告訴RPC框架:B服務器地址、端口,調用函數名稱。所以必須實現待調用方法到call ID的映射。
  • 序列化與反序列化:由於網絡協議都是二進制的,所以調用方法的參數在進行傳遞時首先要序列化成二進制,B服務器收到請求后要再對參數進行反序列化。恢復為內存中的表達方式,找到對應的方法進行本地調用,得到返回值。返回值從B到A的傳輸仍要經過序列化與反序列化的過程。

常見名詞小結

名詞 特點
RPC 遠程過程調用(分布式、微服務間的方法調用)
HTTP 無狀態,每次請求都要發送一個request,服務器響應之后就斷掉(http header中的keep-alive指的是tcp)
TCP 面向連接,三次握手保證通信可靠
UDP 非面向連接,不可靠,速度快(可以手動對數據收發進行驗證,IM系統多采用,QQ)
socket TCP協議的接口實現,面向傳輸層進行網絡編程

單獨來談一談gRPC

gRPC是谷歌開源的一個 RPC 框架,面向移動和 HTTP/2 設計。

  • 內容交換格式采用ProtoBuf(Google Protocol Buffers),開源已久,提供了一種靈活、高效、自動序列化結構數據的機制,作用與XML,Json類似,但使用二進制,(反)序列化速度快,壓縮效率高。
  • 傳輸協議 采用http2,性能比http1.1好了很多

和很多RPC系統一樣,服務端負責實現定義好的接口並處理客戶端的請求,客戶端根據接口描述直接調用需要的服務。客戶端和服務端可以分別使用gPRC支持的不同語言實現。

ProtoBuf 具有強大的IDL(interface description language,接口描述語言)和相關工具集(主要是protoc)。用戶寫好.proto描述文件后,protoc可以將其編譯成眾多語言的接口代碼。

補充:HTTP/2介紹

新特性:
  • 新的二進制格式

    HTTP1.X都是基於文本解析,而因為文本表現形式的多樣性,基於文本協議的格式解析天然存在健壯性問題。而采用二進制格式后實現方便且健壯。

  • 多路復用

    多個request共享一個連接。

  • header壓縮

    在HTTP1.x中header信息很多,且每次都會重復發送,造成很大浪費。HTTP2.0使用encoder減少了傳輸的header大小,且通信雙方都緩存一份包含了header信息的表,此后的請求可以只發送差異數據,避免信息的重復傳輸,進一步減少需要傳輸的內容大小。

  • 服務端推送

    主要的思想是:當一個客戶端請求資源X,而服務器知道它很可能也需要資源Z的情況下,服務器可以在客戶端發送請求前,主動將資源Z推送給客戶端。這個功能幫助客戶端將Z放進緩存以備將來之需。也遵守同源策略,且客戶端可以拒絕推送過來的資源。

鏈接:https://www.jianshu.com/p/959030de7f1c


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM