package
0.0.0-20220929103845-2ebd1957c018
Repository: https://github.com/pandaychen/grpc-wrapper-framework.git
Documentation: pkg.go.dev

# README

简介

atreus 是一个基于 gRPC 封装的脚手架

0x01 错误处理(规范)

服务端错误返回

服务端错误返回需要使用如下代码完成,其中第一个参数来源于 官方,第二个参数为自定义,实现 代码

return status.Error(codes.Internal, pyerrors.InternalError)

客户端错误返回

需要纳入熔断错误计算的类型(超时类、服务器错误等):

  • codes.Unknown:异常错误(recover 拦截器)
  • codes.DeadlineExceeded:服务端 ctx 超时(timeout 拦截器)
  • codes.ResourceExhausted:服务端限速丢弃(limiter 拦截器)

不纳入的(逻辑错误等):

  • codes.InvalidArgument:非法参数(ACL 拦截器)
  • codes.Unauthenticated:未认证(auth 拦截器)
  • codes.InvalidArgument:非法参数(validator 拦截器)

错误的生成方式

所有的错误按照如下建议生成:

  1. 只使用 github.com/pkg/errors 定义的方法来生成(封装)错误
  2. 拦截器中的错误生成,只使用如下方式,不自己构造错误返回:
    • 调用 google.golang.org/grpc/status 包的 Error 方法构造,如 status.Error(codes.InvalidArgument, err.Error()),第一个参数为 grpc 标准错误类型,第二个参数为业务错误,可选为想给用户返回的错误字符串、或者 atreus 全局错误 errcode.MethodNotAllowed.Error()
    • 直接返回 atreus 定义的全局错误,比如服务端限流拦截器返回限流时,直接返回系统默认的错误 errcode.ServiceUnavailable;服务端发生 panic 时,直接返回 ecode.ServerErr,客户端发生熔断丢包时,直接返回 ecode.ServiceUnavailable 即可
    • 如前所说,错误的生成会熔断的错误计数,特别要注意

0x02 参数校验:go.validator 接入 proto 的步骤

使用 github.com/mwitkow/go-proto-validators/protoc-gen-govalidators 包

  1. 设置 GOPATH,如本机的 GOPATH 地址为 /root/go/

  2. 下载 https://github.com/protocolbuffers/protobuf 项目

  3. protobuf/src/* 目录复制到 GOPATH 中的如下路径:

cp src/ ${GOPATH}/src/github.com/google/protobuf/src -r
cp src/ /root/go/src/github.com/google/protobuf/ -r
  1. 下载 protoc-gen-govalidators 包:
go get github.com/mwitkow/go-proto-validators/protoc-gen-govalidators
  1. 编写 proto 文件,注意添加 validator.proto 包及协议字段的 validato 规则
syntax = "proto3";

// protoc -I=. *.proto --go_out=plugins=grpc:.

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

import "github.com/mwitkow/go-proto-validators/validator.proto";

package proto;

//a common RPC names with Serivce suffix
service GreeterService {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
    //rpc ErrorSayHello(HelloRequest) returns  (HelloReply) {}
}

message HelloRequest {
    string name = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}];
}

message HelloReply {
    string message = 1;
}
  1. 生成 pb.govalidator.pb.go 文件,完成:
protoc    --proto_path=${GOPATH}/src   --proto_path=${GOPATH}/src/github.com/google/protobuf/src   --proto_path=.   --go_out=.   --govalidators_out=. --go_out=plugins=grpc:./   *.proto

使用 github.com/envoyproxy/protoc-gen-validate

  1. 安装 protoc-gen-validate 工具
go get -d github.com/envoyproxy/protoc-gen-validate
cd ${GOPATH}/src/github.com/envoyproxy/protoc-gen-validate
make build

安装成功:

GOBIN=/root/go/src/github.com/envoyproxy/protoc-gen-validate/bin go install google.golang.org/protobuf/cmd/[email protected]
protoc -I . \
        --plugin=protoc-gen-go=/root/go//bin/protoc-gen-go \
        --go_opt=paths=source_relative \
        --go_out="Mvalidate/validate.proto=github.com/envoyproxy/protoc-gen-validate/validate,Mgoogle/protobuf/any.proto=google.golang.org/protobuf/types/known/anypb,Mgoogle/protobuf/duration.proto=google.golang.org/protobuf/types/known/durationpb,Mgoogle/protobuf/struct.proto=google.golang.org/protobuf/types/known/structpb,Mgoogle/protobuf/timestamp.proto=google.golang.org/protobuf/types/known/timestamppb,Mgoogle/protobuf/wrappers.proto=google.golang.org/protobuf/types/known/wrapperspb,Mgoogle/protobuf/descriptor.proto=google.golang.org/protobuf/types/descriptorpb:." validate/validate.proto
go install .
go: downloading github.com/lyft/protoc-gen-star v0.5.3
go: downloading github.com/iancoleman/strcase v0.2.0
  1. 编写 proto 文件,如下:
syntax = "proto3";

// protoc -I=. *.proto --go_out=plugins=grpc:.

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";


import "validate/validate.proto";

package proto;

//a common RPC names with Serivce suffix
service GreeterService {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
    //rpc ErrorSayHello(HelloRequest) returns  (HelloReply) {}
}

message HelloRequest {
    string name = 1  [(validate.rules).string = {
                      pattern:   "^[a-z]{2,5}$",
                      max_bytes: 256,
                   }];
}

message HelloReply {
    string message = 1;
}
  1. 编译 proto 文件,生成 pb.gopb.validator.go ,完成。
protoc   -I .   -I ${GOPATH}/src   -I ${GOPATH}/src/github.com/envoyproxy/protoc-gen-validate     --validate_out="lang=go:." --go_out=plugins=grpc:./   *.proto
  1. 规则可见:https://github.com/envoyproxy/protoc-gen-validate#constraint-rules

# Packages

No description provided by the author
No description provided by the author
No description provided by the author

# Functions

metadata API for client.
metadata API for server.
ConvertNormalError convert error for service reply and try to convert it to grpc.Status.
获取调用端IP.
No description provided by the author
判断 err 是否为 ctx 错误(DeadlineExceeded || Canceled).
No description provided by the author
No description provided by the author
以GracefulGrpcAppserver启动并创建Listener.
No description provided by the author
No description provided by the author
Recovery interceptor:必须放在第 0 号链位置.
计时(最后一个拦截器).
ToErrEcode convert grpc.status to ecode.Codes 外部接口.
转换 ctx 错误为 grpc 的标注错误.

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

No description provided by the author

# Structs

客户端封装结构.
No description provided by the author
No description provided by the author
grpc-server核心结构(封装).
No description provided by the author
提供基础xrate的限速实现.

# Interfaces

提供统一的limiter接口.

# Type aliases

No description provided by the author