導讀:gRPC已經是新一代微服務的標準RPC框架。對於實現來說,雖然可以用服務框架等手段來做到負載均衡,業界還沒有針對gRPC的反向代理軟體。NGINIX作為老牌負載均衡軟體對gRPC進行了支援。本文作者簡要介紹了NGINX這一特性。
NGINX將在1.13.10版本中包含grpc相關功能。
這個版本支援NGINX代理gRPC TCP連線。可以用來:
-
釋出gRPC服務,包括未加密/加密的gRPC服務。
-
透過單個endpoint釋出多個gRPC服務,使用NGINX路由到後端服務。 甚至可以和其他HTTP/2服務使用相同的endpoint,例如網站和 REST API。
-
反向代理gRPC服務,對gRPC服務叢集進行負載均衡。
什麼是gRPC?
gRPC是一種rpc協議,用於客戶端和服務端之間的通訊。 gRPC設計的很緊湊並且多語言支援良好,同時支援request/response樣式和流式互動。 由於其廣泛的語言支援和簡單面向使用者的設計,該協議越來越受歡迎,其中包含服務混搭(service mesh)實現 。
無論是明文還是TLS加密,gRPC都透過HTTP/2傳輸。 gRPC request使用HTTP POST請求
。 gRPC response也使用類似的方式,併在response結束時使用HTTP trailer 傳送狀態碼。
因為gRPC使用了HTTP/2的連線復用和流式傳輸功能,所以gRPC不能使用HTTP 1.x。
使用NGINX管理gRPC服務
下麵是一個簡單的gRPC程式作為DEMO。
簡單gRPC服務
首先,我們在客戶端和伺服器應用程式之間插入NGINX。 NGINX為伺服器應用程式提供了一個穩定可靠的閘道器。
註意這裡需要使用帶gRPC功能的NGINX。 如果您想從原始碼構建NGINX,請記住包含http_ssl
和http_v2
模組:
NGINX監聽gRPC流量,並使用grpc_pass
指令代理流量。 下麵的配置是將埠80上加密的gRPC流量轉發到埠50051上的服務:
我們需要確保grpc_pass
指令中的地址是正確的。 重新編譯客戶端以指向NGINX的IP地址和監聽埠。
當執行修改後的客戶端時,會看到與之前相同的響應,但請求是經由GINX轉發。 我們可以在訪問日誌中看到請求記錄:
註意: NGINX不支援在明文(非TLS)埠上同時支援HTTP/1和HTTP/2。 如果你想同時處理兩個協議版本,你應該為每個協議版本建立一個監聽埠。
釋出TLS加密的gRPC服務
上面的示例使用未加密的HTTP/2(明文)進行通訊。 這對測試和部署來說非常簡單,但生產環境需要加密。 你可以使用NGINX來新增這個加密層。
首先建立一個自簽名證書對並修改您的NGINX伺服器配置,如下所示:
修改gRPC客戶端以使用TLS,連線到埠1443,並禁用證書檢查(使用自簽名或不可信證書時需要如此)。 如果你使用的是Go,則需要將crypto/tls
和google.golang.org/grpc/credentials
新增到匯入串列中,並將grpc.Dial()
呼叫修改為以下內容:
這就是需要做的所有工作。 在生產環境中,你還需要將自簽名證書替換為受信任的證書頒發機構(CA)頒發的證書。
反向代理加密的gRPC服務
如果想在內部呼叫對gRPC請求加密。 首先需要修改伺服器應用程式以偵聽TLS加密( grpcs
)連線:
在NGINX配置中,您需要修改將gRPC流量代理到upstream server的協議:
路由
這裡將會介紹如何使用NGINX代理多個gRPC後端服務。
使用NGINX,您可以識別服務和方法,然後使用location
指令路由流量。 您可能已經猜出gRPC請求URL是從proto規範中的包,服務和方法名稱派生的。 考慮如下SayHello
RPC方法:
呼叫SayHello
RPC方法需要從/helloworld.Greeter/SayHello發出POST
請求,如以下日誌條目所示:
使用NGINX路由請求非常簡單:
你可以自己嘗試一下。 例子中擴充套件了Hello World包(在helloworld.proto
)新增一個名為Dispatcher的新服務,然後建立了一個實現Dispatcher方法的新服務。 客戶端使用一個HTTP/2連線向Greeter和Dispatcher服務發出RPC請求。 NGINX會將請求路由到合適的gRPC伺服器。
請註意/ location
塊。 該塊處理與已知gRPC呼叫不匹配的請求。 您可以使用像這樣的location
塊提供網頁內容和其他非gRPC服務。
負載均衡
如何擴充套件gRPC服務以增加容量並提供高可用性? NGINX的upstream group就是做這事的:
當然,如果您的upstream正在監聽TLS,則可以使用grpc_pass
grpcs://upstreams
。
NGINX可以採用一系列負載均衡演演算法來分配後端gRPC伺服器上的gRPC請求。 NGINX的內建狀況檢查將檢測後端服務是否無法響應或者是否產生錯誤,如果檢測到後端服務出問題,NGINX會自動移除該節點。 如果沒有後端節點可用,則會傳回/error502grpc
。
相關閱讀:
微博開源的Motan RPC最新進展:新增跨語言及服務治理支援
本文作者 Owen Garrett 由 Jesse 翻譯。轉載譯文請註明出處,技術原創及架構實踐文章,歡迎透過公眾號選單「聯絡我們」進行投稿。
高可用架構
改變網際網路的構建方式
長按二維碼 關註「高可用架構」公眾號