Nginx 1.13.10新增了對GRPC的原生支持官撼。
安裝Nginx
Nginx版本要求:1.13.10+
gRPC必須使用HTTP/2傳輸數(shù)據(jù)盆色,支持明文和TLS加密數(shù)據(jù),支持流數(shù)據(jù)的交互式塌。這是為了充分利用 HTTP/2 連接的多路復(fù)用和流式特性沼沈。所以在安裝部署nginx時需要安裝http/2伪窖。使用源碼安裝,編譯時需要加入http_ssl和http_v2模塊:
./configure --with-http_ssl_module --with-http_v2_module
Nginx以不加密方式代理不加密GRPC服務(wù)
示例配置:
http {
server {
listen 80 http2;
# server_name localhost;
# access_log logs/host.access.log main;
location / {
grpc_pass grpc://localhost:8200;
}
}
}
指令grpc_pass用來指定代理的gRPC服務(wù)器地址性芬,前綴協(xié)議有兩種: grpc://:與gRPC服務(wù)器端交互是以明文的方式
grpcs://:與gRPC服務(wù)器端交互式以TLS加密方式
Nginx以加密方式代理不加密GRPC服務(wù)
示例:
http {
server {
listen 443 ssl http2;
# server_name localhost;
# access_log logs/host.access.log main;
ssl_certificate ssl/server.crt;
ssl_certificate_key ssl/server.key;
# 另一種證書格式
# ssl_certificate ssl/server.pem;
# ssl_certificate_key ssl/server.pem;
location / {
grpc_pass grpc://localhost:8200;
}
}
}
Nginx根據(jù)路徑代理到不同的GRPC服務(wù)
如果后端有多個gRPC服務(wù)端,其中每個服務(wù)端都是提供不同的gRPC服務(wù)看幼。這種情況可以使用一個nginx接收客戶端請求批旺,然后根據(jù)不同的路徑分發(fā)路由到指定的gRPC服務(wù)器。示例:
http {
server {
listen 80 http2;
# server_name localhost;
# access_log logs/host.access.log main;
location /helloworld.Greeter {
grpc_pass grpc://192.168.1.11:8200;
}
location /helloworld.Dispatcher {
grpc_pass grpc://192.168.1.12:8200;
}
}
}
Nginx對GRPC做負(fù)載均衡
在后端有多個gRPC服務(wù)器诵姜,它們都是同一個gRPC服務(wù)汽煮,這種情況可以結(jié)合nginx的upstream可以對gRPC的請求做負(fù)載均衡。示例:
http {
upstream grpcservers {
server 192.168.1.11:8200;
server 192.168.1.12:8200;
}
server {
listen 80 http2;
# server_name localhost;
# access_log logs/host.access.log main;
location /helloworld.Greeter {
grpc_pass grpc://grpcservers;
}
}
}
Go GRPC客戶端建立連接
連接明文服務(wù)端
conn, err := grpc.Dial("127.0.0.1", grpc.WithInsecure())
if err != nil {
panic(err)
}
helloworld := pb.NewHellowordClient(conn)
連接tls單向認(rèn)證的服務(wù)端
// serverNameOverride 填證書的CN值
tls, err := credentials.NewClientTLSFromFile("./server.crt", "test.com")
if err != nil {
panic(err)
}
conn, err := grpc.Dial("127.0.0.1", grpc.WithTransportCredentials(tls))
if err != nil {
panic(err)
}
helloworld := pb.NewHellowordClient(conn)