Nginx宣布正式支持gRPC,附示例代码
NGINX 官方博客正式宣布 NGINX 支持原生的 gPRC,现在就可以从代码仓库拉取快照版本。该特性将会被包含在 NGINX OSS 1.13.10、NGINX Plus R15 以及 NGINX 1.13.9 当中。
NGINX 已经能够代理 gRPC TCP 连接,用户可以用它:
发布 gRPC 服务,并应用 NGINX 提供的 HTTP/2 TLS 加密机制、速率限定、基于 IP 的访问控制以及日志等功能。
在单个端点上发布多个 gRPC 服务,使用 NGINX 检查方法调用,将各个方法调用路由到相应的服务上。
对一组 gRPC 服务进行负载均衡,可以使用轮询算法、最少连接数原则或其他方式在集群上分发流量。
什么是 gRPC?
gRPC 是一种远程过程调用协议,用于客户端和服务器端之间的通信。gRPC 紧凑小巧,跨多种编程语言,同时支持请求与响应式的交互方式和流式交互方式。gRPC 因其跨语言特性和简洁的设计变得越来越流行,其中服务网格的实现就使用了 gRPC。
gRPC 通过 HTTP/2 传输数据,可以传输明文文本数据和 TLS 加密过的数据。gRPC 调用是通过 HTTP POST 请求来实现的,每个请求里包含了一个编码过的消息体(protocol buffer 是默认的编码方式)。gRPC 的响应消息里也包含一个编码过的消息体,并在消息尾部带上状态码。
gRPC 不能通过 HTTP 进行传输,而必须使用 HTTP/2,这是因为要充分利用 HTTP/2 连接的多路复用和流式特性。
通过 NGINX 来管理 gRPC 服务
下面的示例对 gRPC 的 Hello World 快速入门教程进行了修改,用它来创建一个简单的客户端到服务器端应用。例子中提供了 NGINX 的配置信息,而把应用程序的实现留给读者,不过文中还是会给出一些提示。
1、暴露简单的 gRPC 服务
首先,在客户端和服务器端之间安插 NGINX,NGINX 为服务器端的应用程序提供了一个稳定可靠的网关。
然后开始部署包含了 gRPC 更新包的 NGINX。如果要从源代码开始编译 NGINX,要记得把 http_ssl 和 http_v2 两个模块包含进去:
$ auto/configure --with-http_ssl_module —with-http_v2_module
NGINX 使用一个 HTTP 服务器来监听 gRPC 流量,并使用 grpc_pass 指令来代理 gRPC 流量。像下面的配置那样,在 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.1 - - [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.1 - - [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,如果一定要同时使用两种版本的协议,需要分别为它们创建不同的端口。
2、发布基于 TLS 的 gRPC 服务
Hello World 快速入门教程使用的是未加密的 HTTP/2,这样方便测试和部署,但要部署到生产环境就不能这么简单了。可以通过 NGINX 来增加一个加密层:
创建一个自签名的证书对,然后修改 NGINX 服务器的配置如下:
server {
listen 1443 ssl http2;
ssl_certificate ssl/cert.pem;
ssl_certificate_key ssl/key.pem;
#...
}
让 gRPC 客户端使用 TLS,连接到 1443 端口,并禁用证书检查——这在使用自签名证书或未经信任的证书时是一个必要的步骤。例如,如果使用了 Go 语言编写的示例,就需要导入 crypto/tls 和 google.golang.org/grpc/credentials,并修改 grpc.Dial() 方法:
creds := credentials.NewTLS( &tls.Config{ InsecureSkipVerify: true } )
// 记得修改地址,使用新的端口
conn, err := grpc.Dial( address, grpc.WithTransportCredentials( creds ) )
这样就可以加密 gRPC 流量了。在部署到生产环境时,需要将自签名证书换成由可信任证书机构发布的证书,客户端也需要配置成信任该证书。
3、代理加密的 gRPC 服务
有时候可能需要在内部对 gRPC 流量进行加密,那么就要修改服务器端应用程序的配置,把原先监听未加密(grpc)连接改为监听 TLS 加密(grpcs)连接。
cer, err := tls.LoadX509KeyPair( "cert.pem", "key.pem" )
config := &tls.Config{ Certificates: []tls.Certificate{cer} }
lis, err := tls.Listen( "tcp", port, config )
在 NGINX 的配置里,需要将 grpc-pass 配置成上游服务器的地址:
# Use grpcs for TLS-encrypted gRPC traffic
grpc_pass grpcs://localhost:50051;
4、路由 gRPC 流量
如果同时存在多个 gRPC 服务,并且每个服务是由不同的服务器应用程序提供的,那么该怎么办?如果能够将这些服务通过单个 TLS 端点暴露出来是不是更好?
在 NGINX 里,可以对服务和它的方法稍作修改,然后使用 location 指令来路由流量。gRPC 的请求 URL 是使用包名、服务名和方法名来生成的。比如这个叫作 SayHello 的 RPC 方法:
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
调用这个方法就会生成一个 POST 请求,URL 是 /helloworld.Greeter/SayHello,这个可以从日志中看出来:
192.168.20.1 - - [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.21:50052;
}
location / {
root html;
index index.html index.htm;
}
6、对 gRPC 流量进行负载均衡
那么该如何增加 gRPC 服务的容量,以便提供高可用性?
可以使用 NGINX 的 upstream 组:
upstream grpcservers {
server 192.168.20.21:50051;
server 192.168.20.22:50052;
}
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;
}
}
当然,如果上游监听的是 TLS 端口,可以使用 grpc_pass grpcs://upstreams。
NGINX 支持多种负载均衡算法,其内置的健康检测机制可以检测到无法及时响应或发生错误的服务器,并把它们移除。如果没有可用的服务器,就会返回 /error502grpc 指定的错误消息。
查看原文:https://www.nginx.com/blog/nginx-1-13-10-grpc/
Nginx宣布正式支持gRPC,附示例代码的更多相关文章
- python golang中grpc 使用示例代码详解
python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件 ...
- 漫谈四种神经网络序列解码模型【附示例代码】 glimpse attention
漫谈四种神经网络序列解码模型[附示例代码] http://jacoxu.com/encoder_decoder/ [视觉注意力的循环神经网络模型]http://blog.csdn.net/leo_xu ...
- iOS App集成Apple Pay教程(附示例代码)
苹果在本周一发布了iOS 8.1版本,并正式开放了Apple Pay支付系统.Apple Pay是一个基于NFC的支付系统,不久将被数以万计的线下零售商店予以支持.即便这项科技并不是彻底的突破性进展, ...
- Docker部署FastDFS(附示例代码)
1. FastDFS简介 FastDFS是一个开源的分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文 ...
- 如何实现在Windows上运行Linux程序,附示例代码
微软在去年发布了Bash On Windows, 这项技术允许在Windows上运行Linux程序, 我相信已经有很多文章解释过Bash On Windows的原理, 而今天的这篇文章将会讲解如何自己 ...
- 最佳实践扩展Windows窗体DataGridView控件 .net 4.5 附示例代码
Windows窗体DataGridView控件的性能调优.net 4.5 在处理大量数据时, DataGridView 控制可以消耗大量的内存开销,除非你仔细地使用它. 在客户有限的内存,你可以避 ...
- PyTorch大更新!谷歌出手帮助开发,正式支持TensorBoard | 附5大开源项目
大家又少了一个用TensorFlow的理由. 在一年一度的开发者大会F8上,Facebook放出PyTorch的1.1版本,直指TensorFlow"腹地". 不仅宣布支持Tens ...
- c语言智能指针 附完整示例代码
是的,你没有看错, 不是c++不是c#, 就是你认识的那个c语言. 在很长一段时间里,c的内存管理问题, 层出不穷,不是编写的时候特别费劲繁琐, 就是碰到内存泄漏排查的各种困难, 特别在多线程环境下, ...
- IE下JS读取xml文件示例代码
JS读取xml文件具体步骤为:创建DOM对象.加载xml文件(仅适用于IE)附示例代码,感兴趣的朋友可以参考下,希望对大家有所帮助使用javascript脚本读取xml文件,这里暂只考虑IE浏览器st ...
随机推荐
- PHP中对象是按值传递还是按引用传递?
1.首先,什么是按值传递和按引用传递? 按值传递就是仅仅把值传递过去,相当于传递的是值的拷贝,而按引用传递传递的是内存的地址. 在 PHP5 中,如果按引用传递,就是将 zval 的地址赋给另一个变量 ...
- 使用 idea 产生错误The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized
解决方法 spring.datasource.url=jdbc:mysql://localhost:3306/spring_cache?serverTimezone=GMT%2B8
- Android——MaterialDesign之一Toolbar
Toolbar 由于ActionBar设计原因只能存在活动的顶部,从而不能实现MaterialDesign的效果,现在推荐使用Toolbar,继承Actionbar,但是比起它更加的灵活. 设置主题: ...
- mysql定时任务event——清理过期数据
需要删除数据的表名:t_req_log 建表sql CREATE TABLE `t_req_log` ( `id` ) NOT NULL AUTO_INCREMENT, `host` ) DEFAUL ...
- Java多线程3:Thread中的实例方法
一.Thread类中的方法调用方式 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: ...
- dede:field name=’position’标签调用 主页改成英文Home和改变符号
在用dede:field name=’position’ 这个标签的时候我们调用的这个就是中文的,出现的是主页>+相应的栏目 ,那么这个问题怎么改成英文的呢?有好多大虾都说找到dede安装目录 ...
- 八、.net core 通过数据库配置文件连接操作数据库
一.创建DotNetCore项目 直接创建core项目并不勾选docker支持 二.nuget进行连接MySQL程序集的下载安装 1.MySql.Data.EntityFrameworkCore方式 ...
- 文件上传.ashx
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Runtime ...
- How to proof Pi
可以把圆想象成一个无限增大角的正多边形,通过倍角公式即勾股定理进行迭代. sin2x=2sinxcosx
- Windows & RabbitMQ:集群(clustering) & 高可用(HA)
描述:我们需要配置三台服务器:ServerA, ServerB, ServerC 注意事项: 所有的服务器的Erlang版本,RabbitMQ版本必须一样 服务器名大小写敏感 Step 1:安装Rab ...