1. 程式人生 > 實用技巧 >思考gRPC :為什麼是HTTP/2

思考gRPC :為什麼是HTTP/2

背景

gRPC是google開源的高效能跨語言的RPC方案。gRPC的設計目標是在任何環境下執行,支援可插拔的負載均衡,跟蹤,執行狀況檢查和身份驗證。它不僅支援資料中心內部和跨資料中心的服務呼叫,它也適用於分散式計算的最後一公里,將裝置,移動應用程式和瀏覽器連線到後端服務。

GRPC設計的動機和原則

個人覺得官方的文章令人印象深刻的點:

  • 內部有Stubby的框架,但是它不是基於任何一個標準的
  • 支援任意環境使用,支援物聯網、手機、瀏覽器
  • 支援stream和流控

HTTP/2是什麼

在正式討論gRPC為什麼選擇HTTP/2之前,我們先來簡單瞭解下HTTP/2。

HTTP/2可以簡單用一個圖片來介紹:

來自:https://hpbn.co/

可以看到:

  • HTTP/1裡的header對應HTTP/2裡的 HEADERS frame
  • HTTP/1裡的payload對應HTTP/2裡的 DATA frame

在Chrome瀏覽器裡,開啟chrome://net-internals/#http2,可以看到http2連結的資訊。

目前很多網站都已經跑在HTTP/2上了,包括alibaba。

gRPC over HTTP/2

準確來說gRPC設計上是分層的,底層支援不同的協議,目前gRPC支援:

但是大多數情況下,討論都是基於gRPC over HTTP2。

下面從一個真實的gRPCSayHello請求,檢視它在HTTP/2上是怎樣實現的。用wireshark抓包:

可以看到下面這些Header:

  • Header: :authority: localhost:50051
  • Header: :path: /helloworld.Greeter/SayHello
  • Header: :method: POST
  • Header: :scheme: http
  • Header: content-type: application/grpc
  • Header: user-agent: grpc-java-netty/1.11.0

然後請求的引數在DATA frame裡:

  • GRPC Message: /helloworld.Greeter/SayHello, Request

簡而言之,gGRPC把元資料放到HTTP/2 Headers裡,請求引數序列化之後放到 DATA frame裡。

基於HTTP/2 協議的優點

HTTP/2 是一個公開的標準

Google本身把這個事情想清楚了,它並沒有把內部的Stubby開源,而是選擇重新做。現在技術越來越開放,私有協議的空間越來越小。

HTTP/2 是一個經過實踐檢驗的標準

HTTP/2是先有實踐再有標準,這個很重要。很多不成功的標準都是先有一大堆廠商討論出標準後有實現,導致混亂而不可用,比如CORBA。HTTP/2的前身是Google的SPDY,沒有Google的實踐和推動,可能都不會有HTTP/2。

HTTP/2 天然支援物聯網、手機、瀏覽器

實際上先用上HTTP/2的也是手機和手機瀏覽器。移動網際網路推動了HTTP/2的發展和普及。

基於HTTP/2 多語言客戶端實現容易

只討論協議本身的實現,不考慮序列化。

  • 每個流行的程式語言都會有成熟的HTTP/2 Client
  • HTTP/2 Client是經過充分測試,可靠的
  • 用Client傳送HTTP/2請求的難度遠低於用socket傳送資料包/解析資料包

HTTP/2支援Stream和流控

在業界,有很多支援stream的方案,比如基於websocket的,或者rsocket。但是這些方案都不是通用的。

HTTP/2裡的Stream還可以設定優先順序,儘管在rpc裡可能用的比較少,但是一些複雜的場景可能會用到。

基於HTTP/2 在Gateway/Proxy很容易支援

HTTP/2 安全性有保證

  • HTTP/2 天然支援SSL,當然gRPC可以跑在clear text協議(即不加密)上。
  • 很多私有協議的rpc可能自己包裝了一層TLS支援,使用起來也非常複雜。開發者是否有足夠的安全知識?使用者是否配置對了?運維者是否能正確理解?
  • HTTP/2 在公有網路上的傳輸上有保證。比如這個CRIME攻擊,私有協議很難保證沒有這樣子的漏洞。

HTTP/2 鑑權成熟

  • 從HTTP/1發展起來的鑑權系統已經很成熟了,可以無縫用在HTTP/2上
  • 可以從前端到後端完全打通的鑑權,不需要做任何轉換適配

比如傳統的rpc dubbo,需要寫一個dubbo filter,還要考慮把鑑權相關的資訊通過thread local傳遞進去。rpc協議本身也需要支援。總之,非常複雜。實際上絕大部分公司裡的rpc都是沒有鑑權的,可以隨便調。

基於HTTP/2 的缺點

  • rpc的元資料的傳輸不夠高效

    儘管HPAC可以壓縮HTTP Header,但是對於rpc來說,確定一個函式呼叫,可以簡化為一個int,只要兩端去協商過一次,後面直接查表就可以了,不需要像HPAC那樣編碼解碼。
    可以考慮專門對gRPC做一個優化過的HTTP/2解析器,減少一些通用的處理,感覺可以提升效能。

  • HTTP/2 裡一次gRPC呼叫需要解碼兩次

    一次是HEADERS frame,一次是DATA frame。

  • HTTP/2 標準本身是隻有一個TCP連線,但是實際在gRPC裡是會有多個TCP連線,使用時需要注意。

gRPC選擇基於HTTP/2,那麼它的效能肯定不會是最頂尖的。但是對於rpc來說中庸的qps可以接受,通用和相容性才是最重要的事情。

Google制定標準的能力

近10年來,Google制定標準的能力越來越強。下面列舉一些標準:

  • HTTP/2
  • WebP圖片格式
  • WebRTC 網頁即時通訊
  • VP9/AV1 視訊編碼標準
  • Service Worker/PWA

當然google也並不都會成功,很多事情它想推也失敗了,比如Chrome的Native Client。

gRPC目前是k8s生態裡的事實標準。 gRPC是否會成為更多地方,更大領域的RPC標準?

為什麼會出現gRPC

準確來說為什麼會出現基於HTTP/2的RPC?

個人認為一個重要的原因是,在Cloud Native的潮流下,開放互通的需求必然會產生基於HTTP/2的RPC。即使沒有gRPC,也會有其它基於HTTP/2的RPC。

gRPC在Google的內部也是先用在Google Cloud Platform和公開的API上:https://opensource.google.com/projects/grpc

儘管gRPC它可能替換不了內部的RPC實現,但是在開放互通的時代,不止在k8s上,gRPC會有越來越多的舞臺可以施展。

連結