1
0

rpcserver.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package internal
  2. import (
  3. "fmt"
  4. "net"
  5. "github.com/wuntsong-org/go-zero-plus/core/proc"
  6. "github.com/wuntsong-org/go-zero-plus/core/stat"
  7. "github.com/wuntsong-org/go-zero-plus/internal/health"
  8. "github.com/wuntsong-org/go-zero-plus/zrpc/internal/serverinterceptors"
  9. "google.golang.org/grpc"
  10. "google.golang.org/grpc/health/grpc_health_v1"
  11. )
  12. const probeNamePrefix = "zrpc"
  13. type (
  14. // ServerOption defines the method to customize a rpcServerOptions.
  15. ServerOption func(options *rpcServerOptions)
  16. rpcServerOptions struct {
  17. metrics *stat.Metrics
  18. health bool
  19. }
  20. rpcServer struct {
  21. *baseRpcServer
  22. name string
  23. middlewares ServerMiddlewaresConf
  24. healthManager health.Probe
  25. }
  26. )
  27. // NewRpcServer returns a Server.
  28. func NewRpcServer(addr string, middlewares ServerMiddlewaresConf, opts ...ServerOption) Server {
  29. var options rpcServerOptions
  30. for _, opt := range opts {
  31. opt(&options)
  32. }
  33. if options.metrics == nil {
  34. options.metrics = stat.NewMetrics(addr)
  35. }
  36. return &rpcServer{
  37. baseRpcServer: newBaseRpcServer(addr, &options),
  38. middlewares: middlewares,
  39. healthManager: health.NewHealthManager(fmt.Sprintf("%s-%s", probeNamePrefix, addr)),
  40. }
  41. }
  42. func (s *rpcServer) SetName(name string) {
  43. s.name = name
  44. s.baseRpcServer.SetName(name)
  45. }
  46. func (s *rpcServer) Start(register RegisterFn) error {
  47. lis, err := net.Listen("tcp", s.address)
  48. if err != nil {
  49. return err
  50. }
  51. unaryInterceptorOption := grpc.ChainUnaryInterceptor(s.buildUnaryInterceptors()...)
  52. streamInterceptorOption := grpc.ChainStreamInterceptor(s.buildStreamInterceptors()...)
  53. options := append(s.options, unaryInterceptorOption, streamInterceptorOption)
  54. server := grpc.NewServer(options...)
  55. register(server)
  56. // register the health check service
  57. if s.health != nil {
  58. grpc_health_v1.RegisterHealthServer(server, s.health)
  59. s.health.Resume()
  60. }
  61. s.healthManager.MarkReady()
  62. health.AddProbe(s.healthManager)
  63. // we need to make sure all others are wrapped up,
  64. // so we do graceful stop at shutdown phase instead of wrap up phase
  65. waitForCalled := proc.AddShutdownListener(func() {
  66. if s.health != nil {
  67. s.health.Shutdown()
  68. }
  69. server.GracefulStop()
  70. })
  71. defer waitForCalled()
  72. return server.Serve(lis)
  73. }
  74. func (s *rpcServer) buildStreamInterceptors() []grpc.StreamServerInterceptor {
  75. var interceptors []grpc.StreamServerInterceptor
  76. if s.middlewares.Trace {
  77. interceptors = append(interceptors, serverinterceptors.StreamTracingInterceptor)
  78. }
  79. if s.middlewares.Recover {
  80. interceptors = append(interceptors, serverinterceptors.StreamRecoverInterceptor)
  81. }
  82. if s.middlewares.Breaker {
  83. interceptors = append(interceptors, serverinterceptors.StreamBreakerInterceptor)
  84. }
  85. return append(interceptors, s.streamInterceptors...)
  86. }
  87. func (s *rpcServer) buildUnaryInterceptors() []grpc.UnaryServerInterceptor {
  88. var interceptors []grpc.UnaryServerInterceptor
  89. if s.middlewares.Trace {
  90. interceptors = append(interceptors, serverinterceptors.UnaryTracingInterceptor)
  91. }
  92. if s.middlewares.Recover {
  93. interceptors = append(interceptors, serverinterceptors.UnaryRecoverInterceptor)
  94. }
  95. if s.middlewares.Stat {
  96. interceptors = append(interceptors,
  97. serverinterceptors.UnaryStatInterceptor(s.metrics, s.middlewares.StatConf))
  98. }
  99. if s.middlewares.Prometheus {
  100. interceptors = append(interceptors, serverinterceptors.UnaryPrometheusInterceptor)
  101. }
  102. if s.middlewares.Breaker {
  103. interceptors = append(interceptors, serverinterceptors.UnaryBreakerInterceptor)
  104. }
  105. return append(interceptors, s.unaryInterceptors...)
  106. }
  107. // WithMetrics returns a func that sets metrics to a Server.
  108. func WithMetrics(metrics *stat.Metrics) ServerOption {
  109. return func(options *rpcServerOptions) {
  110. options.metrics = metrics
  111. }
  112. }
  113. // WithRpcHealth returns a func that sets rpc health switch to a Server.
  114. func WithRpcHealth(health bool) ServerOption {
  115. return func(options *rpcServerOptions) {
  116. options.health = health
  117. }
  118. }