我的博客服务器开放了两个端口,一个用于服务 HTTP 请求,一个用于服务客户端的 gRPC 请求。
后来对 gRPC 了解更深入之后,发现其底层的传输层协议其实是基于 HTTP/2 的。同时,看到了 NGINX 官方的 gRPC 支持。 于是想用 NGINX 代理 gRPC 请求,这样就不用再考虑 gRPC 的安全问题了(但 HTTP/2 并非一定是 HTTPS 的)。
安全问题是其一,最大的好处,我觉得是:
不用在配置文件中区别对待 HTTP 和 gRPC 地址了。
检测 NGINX 是否支持
NGINX 从版本 v1.13.10 开始支持 gRPC 代理系列指令(参考:nginx_http_grpc_module),并且开始了ngx_http_v2_module
模块。
可以以下方式查看:
1 2 3 4 5 |
|
可以看到我的版本高于 v1.13.10
并且有 http_v2_module
。
NGINX 的简单配置
然后就可以像下面这样一句话实现代理 gRPC 请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
grpc_pass
跟 proxy_pass
的用法非常类似。
其中,grpc://
是可选的,如果 gRPC 是安全连接,则应该用grpcs://
。
值得注意的是,GRPC 是基于 HTTP/2 的,所以 nginx 在配置的时候也必须配置 HTTP/2 的支持:
1 2 3 |
|
或者,如果是 HTTPS 服务器的话:
1 2 3 4 5 |
|
gRPC 客户端的配置
然后修改你的 gRPC 客户端的代码,把原来的 gRPC 地址改成 NGINX 的地址即可。
注意::gRPC 的地址是没有协议头的,即应去掉 NGINX 地址中的 http://
或 https://
,但是端口却是必填的。比如:
- 你的 nginx 地址是
http://example.com
,则 gRPC 地址:example.com:80
- 你的 nginx 地址是
https://example.com
,则 gRPC 地址:example.com:443
- 你的 nginx 地址是
http://example.com:8080
,则 gRPC 地址:example.com:8080
对于 gRPC 客户端,如果 nginx 是不安全连接(非 HTTPS),则应该使用类似下面的代码:
1 2 3 4 |
|
而如果是安全的(使用了有效的 HTTPS 证书):
1 2 3 4 |
|
而如果是使用了自签(或过期等)证书,并且想忽略安全检测:
1 2 3 4 5 6 |
|
也可以客户端自己添加服务端证书以校验,本文从略,有需要再添加。(考虑到应该少有 nginx 服务器使用不安全的证书)
NGINX 根据 gRPC 方法路由代理
首先,需要知道你的 Protocol Buffer 包的方法全称。
打开你的 PB 生成的RPC 服务对应的*.pb.go
文件,比如:service.pb.go。
然后搜索 Invoke
或者 FullMethod
,你应该会看到类似/protocols.TaoBlog/ListComments
的字符串,这些就是方法全称。
双斜杠//
内的是包名.服务名,然后是方法名。
如果要根据包名.服务名来路由,则可以像下面这样:
1 2 3 4 5 6 7 |
|
NGINX 中 gRPC 服务器的负载均衡
gRPC 微服务很多,负载均衡无可避免。
使用 NGINX 自带的 upstream
即可。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
其它
我只使用了nginx_http_grpc_module
模块的一条指令完成了 NGINX 对 gRPC 的代理。
如果需要更多配置,请参阅 NGINX 相关文档。