目录
  • 前言
  • 一,grpc-gateway介绍
  • 二,grpc-gateway环境准备
  • 二,编写grpc-gateway服务
  • 四,使用gateway生成swagger文档
  • 五,性能对比
    • http -> go -> grpc -> go
    • http -> go -> http -> grpc_gateway -> grpc -> go
  • 六,总结

    前言

    调用,让客户端可以更具自身情况自由选择,服务端工作只需要做一份呢?还别说真还有一个准备好的轮子那就是今天的主角《grpc-gateway》。

    附上:

    博文实例demo:https://github.com/sunmi-OS/grpc-gateway-demo

    grpc-gateway官网:https://github.com/grpc-ecosystem/grpc-gateway

    一,grpc-gateway介绍

    grpc-gateway是protoc的一个插件 。它读取Grpc服务定义,并生成反向代理服务器,将RESTful JSON API请求转换为Grpc的方式调用。主要是根据 google.api.http定义中思想完成的,一下就是grpc-gateway结构图:

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    二,grpc-gateway环境准备

    grpc-gateway使用完全的Go语言进行开发,所以安装起来也非常简单,首先需要获取相关的依赖包

    PS:需要先准备好准备好protoc的环境

    go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
    go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
    go get -u github.com/golang/protobuf/protoc-gen-go
    cd $GOPATH/src/
    mkdir -p grpc-gateway-demo/gateway
    cd grpc-gateway-demo/gateway
    vim gateway.proto
    syntax = "proto3";
    package gateway;
    # 新增以下引入
    import "google/api/annotations.proto";
    message StringMessage {
        string value = 1;
    }
    # 修改方法增加http定义
    # service Gateway {
    #   rpc SayHello Echo(StringMessage) returns (StringMessage) {}
    # }
    service Gateway {
       rpc Echo(StringMessage) returns (StringMessage) {
           option (google.api.http) = {
               post: "/v1/example/echo"
               body: "*"
           };
       }
    }
    

    生成grpc结构文件和gateway文件:

    protoc –proto_path=../ -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis –go_out=plugins=grpc:. gateway.proto

    protoc –proto_path=../ -I/usr/local/include -I. -I$GOPATH/src -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis –grpc-gateway_out=logtostderr=true:. gateway.proto

    最终可以看到以下文件

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    二,编写grpc-gateway服务

    服务端代码:

    cd ..
    vim grpc_service.go
    package main
    import (
        "log"
        "net"
        pb "grpc-gateway-demo/gateway"
        "google.golang.org/grpc"
        "golang.org/x/net/context"
    )
    const (
        PORT = ":9192"
    )
    type server struct {}
    func (s *server) Echo(ctx context.Context, in *pb.StringMessage) (*pb.StringMessage, error) {
        log.Println("request: ", in.Value)
        return &pb.StringMessage{Value: "Hello " + in.Value}, nil
    }
    func main() {
        lis, err := net.Listen("tcp", PORT)
        if err != nil {
            log.Fatalf("failed to listen: %v", err)
        }
        s := grpc.NewServer()
        pb.RegisterGatewayServer(s, &server{})
        log.Println("rpc服务已经开启")
        s.Serve(lis)
    }

    运行grpc服务端:

    go build grpc_service.go
    ./grpc_service

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    编写gateway服务

    vim grpc_gateway.go
    package main
    import (
        "flag"
        "net/http"
        "log"
        "github.com/golang/glog"
        "golang.org/x/net/context"
        "github.com/grpc-ecosystem/grpc-gateway/runtime"
        "google.golang.org/grpc"
        gw "grpc-gateway-demo/gateway"
    )
    var (
        echoEndpoint = flag.String("echo_endpoint", "localhost:9192", "endpoint of Gateway")
    )
    func run() error {
        ctx := context.Background()
        ctx, cancel := context.WithCancel(ctx)
        defer cancel()
        mux := runtime.NewServeMux()
        opts := []grpc.DialOption{grpc.WithInsecure()}
        err := gw.RegisterGatewayHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)
        if err != nil {
            return err
        }
        log.Println("服务开启")
        return http.ListenAndServe(":8080", mux)
    }
    func main() {
        flag.Parse()
        defer glog.Flush()
        if err := run(); err != nil {
            glog.Fatal(err)
        }
    }

    运行网关程序

    go build grpc_gateway.go
    ./grpc_gateway

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    使用http的方式调用网关:

    curl -X POST -k http://localhost:8080/v1/example/echo -d '{"value":" world"}'
    {"value":"Hello  world"}

    四,使用gateway生成swagger文档

    cd gateway
    protoc -I/usr/local/include -I. \
    
      -I$GOPATH/src \
    
      -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
    
      --swagger_out=logtostderr=true:. \
    
      gateway.proto

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    五,性能对比

    对比以下两项:

    http -> go -> grpc -> go

    http -> go -> http -> grpc_gateway -> grpc -> go

    全程使用ab 带 -k进行压测

    http -> go -> grpc -> go

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    http -> go -> http -> grpc_gateway -> grpc -> go

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    Go Grpc Gateway兼容HTTP协议文档自动生成网关

    六,总结

    在GO的场景下基本上4倍差距,但是考虑到本身Go在grpc和http上本身就有3.5倍的差距,本身在同等HTTP的情况下经过grpc-gateway和不经过直接到API差距大概在20~30%左右,这样的性能消耗带来的是兼容HTTP并且还可以自动生成swagger(还可以作为调试工具),何乐而不为呢?

    以上就是Go Grpc Gateway兼容HTTP协议文档自动生成网关的详细内容,更多关于Go Grpc Gateway兼容HTTP的资料请关注其它相关文章!

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。