最近,NGINX在其博客宣布,Nginx 宣布从 1.13.10 开始正式支持 gRPC
如下是正文翻译:
今天,我们很高兴在NGINX 1.13.10上分享gRPC流量的第一个本地支持。下一个NGINX Plus版本R15将包含对gRPC的支持以及对NGINX 1.13.9中引入的HTTP / 2服务器推送支持的支持。
NGINX可以代理gRPC TCP连接。有了这个新功能,您可以终止,检查和路由gRPC方法调用。您可以使用它来:
- 发布gRPC服务,然后使用NGINX应用HTTP / 2 TLS加密,速率限制,基于IP的访问控制列表和日志记录。您可以使用未加密的HTTP / 2(h2c cleartext)操作该服务,或者在服务周围打包TLS加密和认证。
- 通过单个端点发布多个gRPC服务,使用NGINX检查呼叫并将其路由到每个内部服务。您甚至可以对其他HTTPS和HTTP / 2服务使用相同的端点,例如网站和基于REST的API。
- 使用循环法,最少连接或其他方法在集群中分配呼叫,对gRPC服务集群进行负载均衡。然后,您可以在需要额外容量时扩展基于gRPC的服务
要了解更多NGINX HTTP / 2服务器推送和gRPC支持,请注册我们两个实况网络研讨会之一:2018年3月28日上午11:00 CEST或2018年3月29日上午10:00 PDT
什么是gRPC?
gRPC是一种远程过程调用协议,用于客户端和服务器应用程序之间的通信。它被设计为紧凑(节省空间)并且可跨多种语言移植,并且支持请求响应和流式交互。由于其广泛的语言支持和简单的面向用户的设计,协议越来越受欢迎,包括在服务网格实现中。
NGINX代理gRPC流量先通过gRPC更新部署NGINX。如果你想从源代码构建NGINX,请记住包含http_ssl
和http_v2
模块:
$ auto/configure --with-http_ssl_module --with-http_v2_module
NGINX使用HTTP服务器监听gRPC流量,并使用该grpc_pass
指令代理流量。为NGINX创建以下代理配置,在端口80上侦听未加密的gRPC流量并将请求转发到端口50051上的服务器:
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
server {
listen 80 http2;
access_log logs/access.log main;
location / {
# Replace localhost:50051 with the address and port of your gRPC server
# The 'grpc://' prefix is optional; unencrypted gRPC is the default
grpc_pass grpc://localhost:50051;
}
}
}
确保grpc_pass
指令中的地址是正确的。重新编译客户端以指向NGINX的IP地址并监听端口。
当您运行修改后的客户端时,您会看到与以前相同的响应,但交易将由NGINX终止并转发。您可以在您配置的访问日志中看到它们:
$ tail logs/access.log
192.168.20.11 - - [01/Mar/2018:13:35:02 +0000] "POST /helloworld.Greeter/SayHello HTTP/2.0" 200 18 "-" "grpc-go/1.11.0-dev"
192.168.20.11 - - [01/Mar/2018:13:35:02 +0000] "POST /helloworld.Greeter/SayHelloAgain HTTP/2.0" 200 24 "-" "grpc-go/1.11.0-dev"
注意: NGINX不支持在明文(非TLS)端口上同时支持HTTP / 1和HTTP / 2 。它需要有关使用哪个版本的协议的先验知识。如果您想通过明文处理两个协议版本,请为每个协议创建一个监听端口。
使用TLS加密发布gRPC服务
Hello World快速入门示例使用未加密的HTTP / 2(明文)进行通信。这对测试和部署来说非常简单,但它不提供生产部署所需的加密。你可以使用NGINX来添加这个加密层。
NGINX路由和SSL终止gRPC流量使用NGINX,您可以识别服务和方法,然后使用location
指令路由流量。您可能已经推断出每个gRPC请求的URL是从proto规范中的包,服务和方法名称派生的。考虑这个示例SayHello
RPC方法:
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
调用SayHello
RPC方法POST
为/helloworld.Greeter/SayHello发出请求,如以下日志条目所示:
192.168.20.11 - - [01/Mar/2018:13:35:02 +0000] "POST /helloworld.Greeter/SayHello HTTP/2.0" 200 18 "-" "grpc-go/1.11.0-dev"
使用NGINX路由流量非常简单:
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;
}
你可以自己尝试一下。这里我们扩展了示例Hello World包(in helloworld.proto
)以添加一个名为Dispatcher的新服务,然后创建了一个实现Dispatcher方法的新服务器应用程序。客户端使用单个HTTP / 2连接为Greeter和Dispatcher服务发出RPC调用。NGINX将呼叫分开并路由到合适的gRPC服务器。
注意“全部” location
/
块。该块处理与已知gRPC调用不匹配的请求。您可以使用这样的location
块从相同的TLS加密端点提供Web内容和其他非gRPC服务。
负载平衡gRPC呼叫
您现在如何扩展gRPC服务以增加容量并提供高可用性?NGINX的上游团队正是这样做的:
upstream grpcservers {
server 192.168.20.11:50051;
server 192.168.20.12:50051;
}
server {
listen 1443 ssl http2;
ssl_certificate ssl/certificate.pem;
ssl_certificate_key ssl/key.pem;
location /helloworld.Greeter {
grpc_pass grpc://grpcservers;
error_page 502 = /error502grpc;
}
location = /error502grpc {
internal;
default_type application/grpc;
add_header grpc-status 14;
add_header grpc-message "unavailable";
return 204;
}
}
当然,grpc_pass
grpcs://upstreams
如果您的上游用户在TLS上收听,则可以使用。
NGINX可以采用一系列负载平衡算法来分配上游gRPC服务器上的gRPC呼叫。NGINX的内置运行状况检查检测服务器是否无法响应或产生错误,然后使服务器停止运转。如果没有服务器可用,则该/error502grpc
位置将返回符合gRPC的错误消息。