微服务网关(五)grpc代理模块

微服务网关(五)grpc代理模块

GRPC是谷歌出品的一个高性能、开源、通用的RPC框架,基于HTTP/2标准设计,支持普通RPC也支持双向流式传递,相对于thrift连接,它可以多路复用,可传递header头数据

在http请求当中我们可以设置header用来传递数据,grpc底层采用http2协议也是支持传递数据的,采用的是metadata。http传递的是文本形式的文件

Metadata 对于 gRPC 本身来说透明, 它使得 client 和 server 能为对方提供本次调用的信息。rpc传递的是二进制文件

就像一次 http 请求的 RequestHeader 和 ResponseHeader,http header 的生命周期是一次 http 请求, Metadata 的生命周期则是一次 RPC 调用。

GRPC透明代理

不需要实现grpc的IDL结构体

GRPC代理服务器的代理实现:

微服务网关(五)grpc代理模块_第1张图片

请求流程:
微服务网关(五)grpc代理模块_第2张图片

一次grpc服务端的启停

整体上与TCP类似,不过多赘述,只举出不同之处的主体代码

grpcserver.go

func GrpcServerRun() {
   ....
      go func(serviceDetail *dao.ServiceDetail) {
         addr := fmt.Sprintf(":%d", serviceDetail.GRPCRule.Port)
         rb, err := dao.LoadBalancerHandler.GetLoadBalancer(serviceDetail)
         ....
         lis, err := net.Listen("tcp", addr)
         ....
         //设置负载均衡策略
         grpcHandler := reverse_proxy.NewGrpcLoadBalanceHandler(rb)
         s := grpc.NewServer(
            grpc.ChainStreamInterceptor(
               grpc_proxy_middleware.GrpcFlowCountMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcFlowLimitMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcJwtAuthTokenMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcJwtFlowCountMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcJwtFlowLimitMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcWhiteListMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcBlackListMiddleware(serviceDetail),
               grpc_proxy_middleware.GrpcHeaderTransferMiddleware(serviceDetail),
            ),
            grpc.UnknownServiceHandler(grpcHandler),
         )
         ....
          //开启服务
         if err := s.Serve(lis); err != nil {
            log.Fatalf(" [INFO] grpc_proxy_run %v err:%v\n", addr, err)
         }
      }(tempItem)
   }
}

func GrpcServerStop() {
   for _, grpcServer := range grpcServerList {
      grpcServer.GracefulStop()
      log.Printf(" [INFO] grpc_proxy_stop %v stopped\n", grpcServer.Addr)
   }
}

grpc_reverse_proxy.go

func NewGrpcLoadBalanceHandler(lb load_balance.LoadBalance) grpc.StreamHandler {
   return func() grpc.StreamHandler {
      nextAddr, err := lb.Get("")
      if err != nil {
         log.Fatal("get next addr fail")
      }
      director := func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
         c, err := grpc.DialContext(ctx, nextAddr, grpc.WithInsecure())
         md, _ := metadata.FromIncomingContext(ctx)
         outCtx, _ := context.WithCancel(ctx)
         outCtx = metadata.NewOutgoingContext(outCtx, md.Copy())
         return outCtx, c, err
      }
      return proxy.TransparentHandler(director)
   }()
}

你可能感兴趣的:(项目实践,微服务,负载均衡,golang,后端,rpc)