文档:https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware
gRPC是一个非常棒的RPC中间件,它在Golang世界中被广泛采用。然而,上游的gRPC代码库相对比较简单。
这个包及其大部分子包为gRPC提供了通常需要的中间件:用于退休的客户端拦截器、用于输入验证和验证的服务器端拦截器、用于链接所述拦截器的功能、元数据便利方法等等。
func ChainStreamClient(interceptors …grpc.StreamClientInterceptor) grpc.StreamClientInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func ChainStreamServer(interceptors …grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func ChainUnaryClient(interceptors …grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func ChainUnaryServer(interceptors …grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func WithStreamServerChain(interceptors …grpc.StreamServerInterceptor) grpc.ServerOption
func WithUnaryServerChain(interceptors …grpc.UnaryServerInterceptor) grpc.ServerOption
WithStreamServerChain,WithUnaryServerChain是为了简化代码的作用
例如:
s := grpc.NewServer(grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
grpc_auth.UnaryServerInterceptor(AuthInterceptor))))
可以写为
s := grpc.NewServer(grpc_middleware.WithUnaryServerChain(
grpc_auth.UnaryServerInterceptor(AuthInterceptor)))
自定义拦截器,服务端:
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"log"
"net"
pb "study/grpc/protobuf/person"
"github.com/grpc-ecosystem/go-grpc-middleware"
)
// 全局恐慌
func RecoveryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
defer func() {
if e := recover(); e != nil {
err = status.Errorf(codes.Internal, "Panic err: %v", e)
}
}()
return handler(ctx, req)
}
// 日志记录
func LoggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
log.Printf("gRPC method: %s, %v", info.FullMethod, req)
resp, err := handler(ctx, req)
log.Printf("gRPC method: %s, %v", info.FullMethod, resp)
return resp, err
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
opts := grpc_middleware.WithUnaryServerChain(
RecoveryInterceptor, // 全局恐慌
LoggingInterceptor, // 日志记录
)
s := grpc.NewServer(opts) //起一个服务
pb.RegisterPersonserverServer(s,&Server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
自定义拦截器,客户端:
func MyInterceptor() grpc.UnaryClientInterceptor{
// 自己的处理逻辑
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
// 自己的处理逻辑
return invoker(ctx, method, req, reply, cc, opts...)
}
}