• golang 工程组件:grpc-gateway 环境安装+默认网关测试


    grpc-gateway

    grpc-gateway 顾名思义是专门是grpc的网关。也是一个protobuf的编译器,是一个proto的插件。 grpc-gateway就是将http请求处理后转发到对应grpc服务上。很多浏览器,或者客户端开箱不支持grpc,只支持传统的restful API。 grpc网关而且也支持负载,兼容不同版本。

    官方文档

    grpc-gateway

    源码

    架构

    在这里插入图片描述

    大致流程如下

    • 写好服务的proto文件。(代理+grpc)

    • 根据proto文件生成反向代理服务代码

    • 根据proto文件生成grpc服务存根

    • 启动反向代理和grpc

    • 客户端使用http json访问 或别的restful api形式

    环境安装

    protobuf

    protobuf链接

    下载对应环境的porotbuf。解压后bin路径配置环境变量

    插件安装

    博主 go 用的 1.19 + windows,预先安装好protobuf

    go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc- gateway@v2.12.0 
    go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
    
    • 1
    • 2
    • 3

    可以把对应GO_PATH bin下插件的二进制文件拷到对应go安装的bin目录下

    grpc+默认网关测试

    proto文件

    echo.proto

    syntax = "proto3";
    package  echo;
    option go_package = "echo/proto";
    
    
    message User{
      int64 id = 1;
      string name = 2;
      int32 age = 3;
      string phone = 4;
      Addr addr = 5;
    }
    message Addr {
      string province = 1;
      string city = 2;
      string county = 3;
    }
    
    service Echo{
      rpc Get(User) returns (User) {}
      rpc AddOrUpdate(User) returns (User) {}
      rpc Delete(User) returns (User) {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    生成grpc stub
    # 生成message 
    protoc --proto_path=proto --go_out=proto --go_opt=paths=source_relative proto/echo.proto 
    # 生成grpc service 
    protoc --proto_path=proto --go-grpc_out=proto --go-grpc_opt=paths=source_relative proto/echo.proto
    
    • 1
    • 2
    • 3
    • 4
    生成默认网关
    # 生成gateway protoc --proto_path=proto  --grpc-gateway_out=proto  --grpc-gateway_opt logtostderr=true  --grpc-gateway_opt paths=source_relative  --grpc-gateway_opt generate_unbound_methods=true  proto/echo.proto
    
    • 1
    grpc服务器代码

    server.go

    package server
    
    import (
        "context"
        "echo/proto"
        "fmt"
    )
    
    type echoServer struct {
        proto.UnimplementedEchoServer
    }
    
    func NewServer() proto.EchoServer {
        return &echoServer{}
    }
    func (s *echoServer) Get(ctx context.Context, in *proto.User) (*proto.User, error) {
        fmt.Printf("%+v\n", in)
        return in, nil
    }
    func (s *echoServer) AddOrUpdate(ctx context.Context, in *proto.User) (*proto.User, error) {
        fmt.Printf("%+v\n", in)
        return in, nil
    }
    func (s *echoServer) Delete(ctx context.Context, in *proto.User) (*proto.User, error) {
        fmt.Printf("%+v\n", in)
        return in, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    gateway代码

    这里直接用官网http代理的代码。需要修改端口和引用自己的grpc服务和网关package

    gateway.go

    package gateway
    
    import (
        "context"
        "flag"
        "net/http"
    
        "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
        "google.golang.org/grpc"
        "google.golang.org/grpc/credentials/insecure"
        _ "google.golang.org/grpc/grpclog"
    
        gw "echo/proto"  // Update
    )
    
    var (
        // command-line options:
        // gRPC server endpoint
        grpcServerEndpoint = flag.String("grpc-server-endpoint",  "localhost:50051", "gRPC server endpoint")
    )
    
    func Run() error {
        ctx := context.Background()
        ctx, cancel := context.WithCancel(ctx)
        defer cancel()
    
        // Register gRPC server endpoint
        // Note: Make sure the gRPC server is running properly and accessible
        mux := runtime.NewServeMux()
        opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
        // 注册对应grpc服务端点handler
        err := gw.RegisterEchoHandlerFromEndpoint(ctx, mux,  *grpcServerEndpoint, opts)
        if err != nil {
            return err
        }
    
        // Start HTTP server (and proxy calls to gRPC server endpoint)
        return http.ListenAndServe(":8081", mux)
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    测试

    main.go

    package main
    
    import (
        "context"
        "echo/echo_server/gateway"
        "echo/echo_server/server"
        "echo/proto"
        "fmt"
        "google.golang.org/grpc"
        "log"
        "net"
        "os"
        "os/signal"
        "time"
    )
    
    func main() {
        // 先启动grpc service
        go func() {
            if err := run(); err != nil {
                log.Fatal(err)
            }
        }()
        time.Sleep(time.Second * 2)
        //后启动gateway
        go func() {
            if err := gateway.Run(); err != nil {
                log.Fatal(err)
            }
        }()
    
        ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
        defer stop()
        <-ctx.Done()
    }
    
    func run() error {
        lis, err := net.Listen("tcp", ":50051")
        if err != nil {
            log.Fatal(err)
        }
        s := grpc.NewServer()
        userServiceServer := server.NewServer()
        proto.RegisterEchoServer(s, userServiceServer)
        fmt.Println("listening ")
        return s.Serve(lis)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    默认路由

    路由为proto文件中{包名}.{服务名}/{方法}。 gateway对外默认是post方法

    PS D:\GIT\gorun\grpc-gateway-practice\echo> Invoke-RestMethod -Uri "http://10.5.81.57:8081/echo.Echo/Get" -Method Post
    
    
    id    : 0
    name  :
    age   : 0
    phone :
    addr  :
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    用postman更方便些

    总结

    • grpc-gateway 只是提供一个反向代理,可以通过配置进行grpc版本兼容。

    • grpc-gateway对外提供restful API风格的http接口,更好兼容各种客户端接入,无需grpc客户端

  • 相关阅读:
    python基础知识入门
    使用达梦数据库的总结
    2022-08-20 C++并发编程(十三)
    Servlet
    Unity-Input System新输入系统插件学习
    2、Linux权限理解
    Docker部署Logstash 7.2.0
    吃啥大转盘
    助你上手Vue3全家桶之Vue3教程
    阿里巴巴中国站item_search_img按图搜索1688商品(拍立淘) API 返回值说明
  • 原文地址:https://blog.csdn.net/qq_43058348/article/details/133993275