gRPC是一种与语言无关的高性能远程过程调用 (RPC) 框架。gRPC 的主要好处是:
这些优势使 gRPC 非常适合:
grpc-json转码器是Envoy中的一个过滤器,它允许 RESTful JSON API 客户端通过 HTTP 向 Envoy 发送请求并代理到 gRPC 服务。
大家可以参考envoy官方文档:https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_json_transcoder_filter
下面我们来通过Envoy的grpc-json转码器实现grpc服务的代理。
.NET中的grpc可以参考官方文档来实现。我们通过vs创建两个默认的grpc server:GrpcService1与GrpcService2,来实现grpc的负载。
我们需要基于默认Grpc模板项目做出以下修改
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("http://*:6001").UseStartup<Startup>();
});
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("http://*:6002").UseStartup<Startup>();
});
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello 1 " + request.Name
});
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello 2 " + request.Name
});
}
修改完之后我们启动两个Grpc Server
Envoy必须知道GRPC服务的proto描述符才能REST API转码,我们可以通过以下链接下载proto工具 https://github.com/protocolbuffers/protobuf/releases
下载完成之后,通过以下命令生成描述符,生成的描述符需要和配置文件一起挂载进容器
protoc.exe --descriptor_set_out=C:\greet.pb --include_imports C:\greet.proto --proto_path=C://
Grpc相关的配置可以参考官方文档,其中需要注意的是以下几点
具体配置如下
admin:
address:
socket_address: {address: 0.0.0.0, port_value: 9901}
static_resources:
listeners:
- name: listener1
address:
socket_address: {address: 0.0.0.0, port_value: 10000}
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: grpc_json
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: {prefix: "/greet.Greeter"}
route: {cluster: grpc, timeout: 60s}
http_filters:
- name: envoy.filters.http.grpc_json_transcoder
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
proto_descriptor: "/etc/envoy/greet.pb"
services: ["greet.Greeter"]
print_options:
add_whitespace: true
always_print_primitive_fields: true
always_print_enums_as_ints: false
preserve_proto_field_names: false
auto_mapping: true
- name: envoy.filters.http.router
clusters:
- name: grpc
type: static
lb_policy: ROUND_ROBIN
dns_lookup_family: V4_ONLY
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: grpc
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 192.168.43.94
port_value: 6001
- endpoint:
address:
socket_address:
address: 192.168.43.94
port_value: 6002
需要特别注意的是,我们需要将envoy.yaml和描述文件都映射到我们的容器内
docker run --rm -it -p 9902:9902 -p 10000:10000 -v D:/gateway/envoy/config/grpc/:/etc/envoy/ -v D:/gateway/envoy/logs:/logs envoyproxy/envoy-dev -c /etc/envoy/envoy.yaml
测试的时候需要注意的是
通过postman调用接口来看,我们成功利用GRPC-Json转码器实现了grpc的代理,并实现了grpc的负载!!