思考gRPC :為什麼是HTTP/2
背景
gRPC是google開源的高效能跨語言的RPC方案。gRPC的設計目標是在任何環境下執行,支援可插拔的負載均衡,跟蹤,執行狀況檢查和身份驗證。它不僅支援資料中心內部和跨資料中心的服務呼叫,它也適用於分散式計算的最後一公里,將裝置,移動應用程式和瀏覽器連線到後端服務。
GRPC設計的動機和原則
個人覺得官方的文章令人印象深刻的點:
- 內部有Stubby的框架,但是它不是基於任何一個標準的
- 支援任意環境使用,支援物聯網、手機、瀏覽器
- 支援stream和流控
HTTP/2是什麼
在正式討論gRPC為什麼選擇HTTP/2之前,我們先來簡單瞭解下HTTP/2。
HTTP/2可以簡單用一個圖片來介紹:
可以看到:
- 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很容易支援
- nginx對gRPC的支援:https://www.nginx.com/blog/nginx-1-13-10-grpc/
- envoy對gRPC的支援:https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/grpc#
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可以接受,通用和相容性才是最重要的事情。
- 官方的benchmark:https://grpc.io/docs/guides/benchmarking.html
- https://github.com/hank-whu/rpc-benchmark
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會有越來越多的舞臺可以施展。