ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Envoy实现.NET架构的网关(三)代理GRPC

2021-10-31 09:32:36  阅读:317  来源: 互联网

标签:网关 http GRPC envoy Envoy grpc filters address type


什么是GRPC

gRPC是一种与语言无关的高性能远程过程调用 (RPC) 框架。gRPC 的主要好处是:

  • 现代、高性能、轻量级的 RPC 框架。
  • 契约优先的 API 开发,默认使用协议缓冲区,与语言无关的实现。
  • 可用于多种语言的工具来生成强类型服务器和客户端。
  • 支持客户端、服务器和双向流调用。
  • 通过 Protobuf 二进制序列化减少网络使用。

这些优势使 gRPC 非常适合:

  • 效率至关重要的轻量级微服务。
  • 需要多种语言进行开发的多语言系统。
  • 需要处理流请求或响应的点对点实时服务。

什么是grpc-json转码器

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服务的代理。

创建grpc服务

.NET中的grpc可以参考官方文档来实现。我们通过vs创建两个默认的grpc server:GrpcService1与GrpcService2,来实现grpc的负载。

我们需要基于默认Grpc模板项目做出以下修改

  • 固定Grpc的端口,修改GrpcService1的默认端口为6001
  • 固定Grpc的端口,修改GrpcService2的默认端口为6002
  • 为了判断是否实现负载,我们修改GrpcService1的SayHello方法返回体,让其返回字符串Hello 1
  • 为了判断是否实现负载,我们修改GrpcService2的SayHello方法返回体,让其返回字符串Hello 2
        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

Grpc服务描述符

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://

配置Envoy

Grpc相关的配置可以参考官方文档,其中需要注意的是以下几点

  • 我们需要将dns_type改为static,因为我们grpc用的是ip而不是域名
  • 并且需要指定auto_mapping: true,这样就可以在我们没有设置http method的情况下路由到我们的grpc服务中的方法
  • 指定grpc描述符,让Envoy知道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

需要特别注意的是,我们需要将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

测试

测试的时候需要注意的是

  • 转码器过滤器处理的请求路径规则是/<package>.<service>/<method>
  • 我们需要使用POST方法。

 

 通过postman调用接口来看,我们成功利用GRPC-Json转码器实现了grpc的代理,并实现了grpc的负载!!

标签:网关,http,GRPC,envoy,Envoy,grpc,filters,address,type
来源: https://www.cnblogs.com/chenyishi/p/15488352.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有