【Backend】用 NGINX 對 gRPC Server 進行 load balancing

Zam Huang
2 min readJul 31, 2020

--

前言

NGINX 在 2018 正式推出支援 gRPC proxy module,到了今年 2020,還推出了 gRPC 相關的 directives,這些都讓 NGINX 具備 proxy gRPC 的能力。而且還非常實用!

2018–03–20
nginx-1.13.10 mainline version has been released, featuring the gRPC proxy module.

2018–04–17
nginx-1.14.0 stable version has been released, incorporating new features and bug fixes from the 1.13.x mainline branch — including the mirror module, HTTP/2 push, the gRPC proxy module, and more.

2020–04–21
nginx-1.18.0 stable version has been released, incorporating new features and bug fixes from the 1.17.x mainline branch — including the dry run mode in limit_req and limit_conn, variables support in the limit_rate, limit_rate_after, and grpc_pass directives, the auth_delay directive, and more.

NGINX 跟 gRPC 在 load balancing 的角色

從這圖可以看出,不同 client 來的 gRPC traffic,其實都當 NIGIX 為接口,並 route traffic 到內部的 gRPC server。而這篇就是要介紹如何設定 NGINX config,讓 NGINX 替你導流量。

NGINX load balancing gRPC

基本上使用 gRPC 所使用的資料格式,都會是 protobuf,而下面就是我們會使用的 package 範例。

package helloworld;

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
service Dispatcher {
rpc DispatchHello (HelloRequest) returns (HelloReply) {}
}

而 NGINX 其實就是根據你的 request URL 來判斷如何分流,因此你必須先知道 Protobuf 中定義的 service 跟實際發送的 URL 會是什麼樣子

192.168.20.11 - - [01/Mar/2018:13:35:02 +0000] "POST /helloworld.Greeter/SayHello HTTP/2.0" 200 18 "-" "grpc-go/-dev"192.168.20.11 - - [01/Mar/2018:13:35:02 +0000] "POST /helloworld.Dispatcher/DispatchHello HTTP/2.0" 200 18 "-" "grpc-go/dev"

NGINX location

而在 NGINX 的 nginx.conf 裡,你就可以這麼定義分成三個部分。

  • 經由 helloworld.Greeter 會導入 192.168.20.11:50051這台 server
  • 經由 helloworld.Dispatcher 會導入 192.168.20.11:50052這台 server
  • 而非以上兩種,不管你是忘記還是刻意,他都會進入到 catch-all ( / ),就像是 switch-case 的 default
location /helloworld.Greeter {
grpc_pass grpc://192.168.20.11:50051;
}

location /helloworld.Dispatcher {
grpc_pass grpc://192.168.20.11:50052;
}

location / {
root html;
index index.html index.htm;
}

NGINX upstream

這個方便將多個分類放在一起或命名,你也可以選擇直接透過 grpc_pass 指定就好,不用刻意指出 upstream。

但他還是有非常實用的地方,讓每個 upstream 間可以有各自的設定,例如可以設定裡面 server 的權重讓效能好的機器吃較多的流量,並且也可透過命名快速知道是什麼用途。

NGINX grpc_pass

設定 gRPC server address,這可以有很多方式

domain, IP and port OP

grpc_pass localhost:9000;

UNIX-domain socket path

grpc_pass unix:/tmp/grpc.socket;

grpc 或 grpcs (TLS)

不給也可以,預設會是 grpc://

grpc_pass grpc://127.0.0.1:9000;

grpc_pass grpcs://127.0.0.1:443;

範例 nginx.conf

Reference

--

--

Zam Huang
Zam Huang

Written by Zam Huang

一個記錄著自己人生過程的工程師。A Software Engineer at Ruckus Network in Taiwan。 IG, Linkedin:@zam_huang, stack overflow: user:2613194

No responses yet