通过Envoy将grpc转换为http json

通过Envoy将grpc转换为http json

转载自微信公众号:niceelegant

一/检查grpc安装

后端服务之间的通信使用gRPC是常规方案,通过proto文件定义交互接口,通过工具生成gRPC

原始proto文件(截取自 grpc/example/helloworld.proto)

 21 package helloworld;
 22
 23 // The greeting service definition.
 24 service Greeter {
 25   // Sends a greeting
 26   rpc SayHello (HelloRequest) returns (HelloReply) {}
 27 }
 28
 29 // The request message containing the user's name.
 30 message HelloRequest {
 31   string name = 1;
 32 }
 33
 34 // The response message containing the greetings
 35 message HelloReply {
 36   string message = 1;
 37 }

首先检查grpc安装是否有问题,测试运行grpc example 是否正常

$ pwd    
$GOPATH/src/google.golang.org/grpc/examples/helloworld
$ go run greeter_server/main.go

//另一个窗口  another terminal
$ pwd
$GOPATH/src/google.golang.org/grpc/examples/helloworld
$ go run greeter_client/main.go
2019/04/03 10:53:00 Greeting: Hello world

如果以上步骤 都正常 ,那么grpc本身安装是没有问题的,如果出现故障,那么请参考grpc安装的文档。

二/配置准备

2.1 安装GOOGLEAPIS包
$ pwd
  $GOPATH/src/github.com/googleapis/
$ git clone https://github.com/googleapis/googleapis
  GOOGLEAPIS_DIR=<your-local-googleapis-folder>
$ echo $GOOGLEAPIS_DIR
  $GOPATH/src/github.com/googleapis/googleapis

配置环境变量 export GOOGLEAPIS_DIR= $GOPATH/src/github.com/googleapis/googleapis

2.2 修改proto文件
 14
 15 syntax = "proto3";
 16
 17 option java_multiple_files = true;
 18 option java_package = "io.grpc.examples.helloworld";
 19 option java_outer_classname = "HelloWorldProto";
 20 import "google/api/annotations.proto";   // #add
 21
 22 package helloworld;
 23
 24 // The greeting service definition.
 25 service Greeter {
 26   // Sends a greeting
 27   rpc SayHello (HelloRequest) returns (HelloReply) {
 28        option (google.api.http) = {        // #add
 29                    post: "/say"            // #add
 30                     body: "*"              // #add
 31
 32            };                              // #add
 33       }
 34
 35 }
 36


增加了 import “google/api/annotations.proto”;

增加了 option (google.api.http) 部分,主要作用是http请求路径

三/ Envoy配置与运行

3.1 envoy yml配置 s2s-grpc-envoy.yaml

static_resources:
  listeners:
  - name: listener1
    address:
      socket_address: { address: 0.0.0.0, port_value: 51051 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          stat_prefix: grpc_json
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { cluster: grpc, timeout: { seconds: 60 } }
          http_filters:
          - name: envoy.grpc_json_transcoder
            config:
              proto_descriptor: "/data/envoy/proto.pb"     #
              services: ["helloworld.Greeter"]             #
              print_options:
                add_whitespace: true
                always_print_primitive_fields: true
                always_print_enums_as_ints: false
                preserve_proto_field_names: false
          - name: envoy.router

  clusters:
  - name: grpc
    connect_timeout: 1.25s
    type: logical_dns
    lb_policy: round_robin
    dns_lookup_family: V4_ONLY
    http2_protocol_options: {}
    load_assignment:
      cluster_name: grpc
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                  address:  127.0.0.1  # host.docker.internal
                  port_value: 50051

3.2 docker 脚本

   protoc -I$GOOGLEAPIS_DIR -I. --include_imports --include_source_info   --descriptor_set_out=proto.pb  helloworld.proto
   echo "---------------------"
  
   docker run -it --rm --name envoy   --network="host"   \
    -v "$(pwd)/proto.pb:/data/envoy/proto.pb:ro" \
      -v "$(pwd)/s2s-grpc-envoy.yaml:/etc/envoy/envoy.yaml:ro" \
      envoyproxy/envoy

作用含义:

1/解析 helloworld.proto 输出为 proto.pb

2/ docker运行脚本 以host模式运行,可以访问本地服务 同时load proto.pb .yml

输出日志中有: starting main dispatch loop 基本说明配置ok

3.3 运行grpc client

开一个 terminal 运行

$ pwd    
$GOPATH/src/google.golang.org/grpc/examples/helloworld
$ go run greeter_server/main.go

四 测试http 访问grpc接口

curl -X POST \
  http://localhost:51051/say \
  -H 'Content-Type: application/json' \
  -d '{
	"name":"banana"
}'

正常返回值

 "message": "Hello banana"

五/错误处理

5.1 http header里面 关注以下两个

**grpc-status

**grpc-message

根据报错信息处理

5.2 no healthy upstream 错误

原因是 无法 访问到 上一级服务 gRPC server

主要检查yml中的 ip port是否正确 容器内是否能访问到gRPC server

         clusters: 
        socket_address:
              address:  127.0.0.1  # host.docker.internal
              port_value: 50051

本文使用的模式 是

参考文档:

A Guide to Envoy’s Backpressure

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 C++ 实现 HTTP 接口,可以使用 gRPCHTTP/1.1 网关。gRPCHTTP/1.1 网关是一个 gRPC 服务器,它将 RESTful HTTP API 转换gRPC。这个网关可以用于将现有的 RESTful HTTP API 转换gRPC,或者让 gRPC 服务提供 RESTful HTTP API。 以下是实现过程的一些步骤: 1. 安装和设置 gRPC:在 C++ 中使用 gRPC,需要安装 gRPC 和 Protocol Buffers。可以从 gRPC 官方网站下载和安装 gRPC。 2. 定义 proto 文件:定义包含 HTTP 端点和请求/响应消息的 proto 文件。可以使用 protobuf 编译器将 proto 文件编译成 C++ 代码。 3. 实现 gRPC 服务:实现 gRPC 服务并编写处理程序来处理 HTTP 端点。 4. 配置 HTTP/1.1 网关:配置 HTTP/1.1 网关,使其将 RESTful HTTP API 转换gRPC。 5. 启动 HTTP/1.1 网关:启动 HTTP/1.1 网关,并且可以使用 RESTful HTTP API 访问 gRPC 服务。 在实现过程中,需要注意以下几点: 1. 在定义 proto 文件时,需要使用 HTTP 规范定义请求/响应消息。 2. 在实现 gRPC 服务时,需要根据 HTTP 规范处理 HTTP 请求和响应。 3. 在配置 HTTP/1.1 网关时,可以使用 Envoy 或 Istio 这样的开源代理来进行配置。 4. 在启动 HTTP/1.1 网关时,需要将其绑定到正确的端口,以便可以使用 RESTful HTTP API 访问 gRPC 服务。 总体来说,使用 gRPCHTTP/1.1 网关可以在 C++ 中实现 HTTP 接口,同时也可以让 gRPC 服务提供 RESTful HTTP API。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值