文档: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

  1. WithStreamServerChainWithUnaryServerChain是为了简化代码的作用
  2. 例如:
  3. s := grpc.NewServer(grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
  4. grpc_auth.UnaryServerInterceptor(AuthInterceptor))))
  5. 可以写为
  6. s := grpc.NewServer(grpc_middleware.WithUnaryServerChain(
  7. grpc_auth.UnaryServerInterceptor(AuthInterceptor)))

自定义拦截器,服务端:

  1. package main
  2. import (
  3. "context"
  4. "google.golang.org/grpc"
  5. "google.golang.org/grpc/codes"
  6. "google.golang.org/grpc/status"
  7. "log"
  8. "net"
  9. pb "study/grpc/protobuf/person"
  10. "github.com/grpc-ecosystem/go-grpc-middleware"
  11. )
  12. // 全局恐慌
  13. func RecoveryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
  14. defer func() {
  15. if e := recover(); e != nil {
  16. err = status.Errorf(codes.Internal, "Panic err: %v", e)
  17. }
  18. }()
  19. return handler(ctx, req)
  20. }
  21. // 日志记录
  22. func LoggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
  23. log.Printf("gRPC method: %s, %v", info.FullMethod, req)
  24. resp, err := handler(ctx, req)
  25. log.Printf("gRPC method: %s, %v", info.FullMethod, resp)
  26. return resp, err
  27. }
  28. func main() {
  29. lis, err := net.Listen("tcp", port)
  30. if err != nil {
  31. log.Fatalf("failed to listen: %v", err)
  32. }
  33. opts := grpc_middleware.WithUnaryServerChain(
  34. RecoveryInterceptor, // 全局恐慌
  35. LoggingInterceptor, // 日志记录
  36. )
  37. s := grpc.NewServer(opts) //起一个服务
  38. pb.RegisterPersonserverServer(s,&Server{})
  39. if err := s.Serve(lis); err != nil {
  40. log.Fatalf("failed to serve: %v", err)
  41. }
  42. }

自定义拦截器,客户端:

  1. func MyInterceptor() grpc.UnaryClientInterceptor{
  2. // 自己的处理逻辑
  3. return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
  4. // 自己的处理逻辑
  5. return invoker(ctx, method, req, reply, cc, opts...)
  6. }
  7. }