GRPC 的功能、使用方式以及配套的生态工具

Tags: grpc 

目录

说明

grpc 具备多种常用的功能,比如 Authentication、Flow Control 等等。

配套的生态工具

grpc-ecosystem 中有多个和 grpc 相关的生态项目,比如:

grpc-gateway:将 grpc 服务转换成 http 服务

grpc-gateway 根据 proto 文件生成处理 http 请求的代码,这写代码将收到的 http 请求转换成对 grpc 服务的调用。

标记字段映射关系

用注解标记映射关系需要更改接口定义文件。如果不能修改接口定义文件,可以:

  • 方法1:生成 generate_unbound_methods,uri 为 servername/methodname
  • 方法2:用单独的一个文件描述 rest 接口和 rpc 接口之间的映射关系。

具体用法见:gRPC API Configuration

如果使用注解标记,需要将下面的文件复制到本地项目 idl 目录的 google/api 中,就可以使用其中的 option google.api.http 进行标注。

google.api.http 支持参数都列在 google/api/http.proto 中的 HttpRule 结构体中,用途分别如下:

  • selector
  • pattern 指定使用的 http method,指定 rpc 接口参数和 uri 路径参数的映射关系
  • body 指定映射到 http request body 的 rpc 参数
  • response_body 指定映射到 http response body 的 rpc 响应参数
message HttpRule {
  string selector = 1;
  oneof pattern {
    string get = 2;
    string put = 3;
    string post = 4;
    string delete = 5;
    string patch = 6;
    CustomHttpPattern custom = 8;
  }
  string body = 7;
  string response_body = 12;
  repeated HttpRule additional_bindings = 11;
}

路径参数指定方式如下(example/library/v1/library.proto),定义了两个路径参数 schelves 和 books,其中 schelves 对应请求参数中的 name。Google 的 api 使用了这种风格的路径参数:google api

  rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=shelves/*/books/*}"
    };
    option (google.api.method_signature) = "name";
  }

生成 http 服务代码

代码生成需要在 protoc-gen-go 和 protoc-gen-go-grpc 之外,再安装两个 protoc 插件:

go install \
    github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest \
    github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest \

然后用 protoc 生成转换 http 请求的代码:

protoc -I ./idl --grpc-gateway_out  ./ \
    --grpc-gateway_opt module=NAME \
    ./idl/NAME/v1beta/*.proto    \
    ./idl/NAME/v1beta/*/*.proto

然后在 grpc 服务中启动一个 http 服务注入生成的 handler

func RunHttpServer(ctx context.Context, services []Service) {
    mux := runtime.NewServeMux(
        runtime.WithIncomingHeaderMatcher(func(key string) (string, bool) {
            return runtime.DefaultHeaderMatcher(key)
        }),
        runtime.WithOutgoingHeaderMatcher(func(key string) (string, bool) {
            return key, true
        }),
        runtime.WithOutgoingTrailerMatcher(func(key string) (string, bool) {
            return key, true
        }),
    )

    opts := []grpc.DialOption{
        grpc.WithTransportCredentials(insecure.NewCredentials()),
        grpc.WithStatsHandler(otelgrpc.NewClientHandler()),
        grpc.WithChainUnaryInterceptor(interceptor.ClientTraceUnary),
        grpc.WithChainStreamInterceptor(interceptor.ClientTraceStream)}

    err = frontend.RegisterFrontendApiServiceHandlerFromEndpoint(ctx, mux, conf.GetHTTPBackend()/*grpc服务的地址*/, opts)
    if err != nil {
        utils.FATAL(ctx, "failed to register http handler", map[string]interface{}{"err": err, "srv": srv})
    }

    utils.INFO(ctx, "http listening at "+conf.GetHTTPListenAddr(), nil)
    if err = http.ListenAndServeTLS(conf.GetHTTPListenAddr(), conf.GetHTTPCert(), conf.GetHTTPKey(), mux); err != nil {
        utils.FATAL(ctx, "http serve fail", map[string]interface{}{"err": err})
    }
}

生成 http 接口描述文件

指定服务在 proto 文件,生成一个 swagger 格式的接口说明文件:

protoc -I ./idl --openapiv2_out  ./ \
    --openapiv2_opt output_format=json \
    ./idl/NAME/v1beta/*.proto    \

参考

  1. 李佶澳的博客
  2. grpc Guides
  3. grpc Metadata
  4. grpc examples/features
  5. grpc-ecosystem
  6. grpc-gateway
  7. google/api/http.proto
  8. google/api/annotations.proto
  9. example/library/v1/library.proto
  10. google api
  11. go-grpc-middleware
  12. grpc api configuration

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  系统软件  程序语言  运营经验  水库文集  网络课程  微信网文  发现知识星球