zoukankan      html  css  js  c++  java
  • Envoy实现.NET架构的网关(三)代理GRPC

    什么是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的负载!!

  • 相关阅读:
    基本数据类型相互转换及操作方法
    python以及计算机原理基础简要摘录
    Linux程序包管理
    rpm命令详解
    Linux程序包管理
    Linux任务计划
    压缩,解压缩工具及bash脚本编程
    btrfs文件系统管理与应用
    LVM应用
    CSS核心技术
  • 原文地址:https://www.cnblogs.com/chenyishi/p/15488352.html
Copyright © 2011-2022 走看看