rpcserver.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package internal
  2. import (
  3. "fmt"
  4. "net"
  5. "github.com/zeromicro/go-zero/core/proc"
  6. "github.com/zeromicro/go-zero/core/stat"
  7. "github.com/zeromicro/go-zero/internal/health"
  8. "github.com/zeromicro/go-zero/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. healthManager health.Probe
  24. }
  25. )
  26. // NewRpcServer returns a Server.
  27. func NewRpcServer(addr string, opts ...ServerOption) Server {
  28. var options rpcServerOptions
  29. for _, opt := range opts {
  30. opt(&options)
  31. }
  32. if options.metrics == nil {
  33. options.metrics = stat.NewMetrics(addr)
  34. }
  35. return &rpcServer{
  36. baseRpcServer: newBaseRpcServer(addr, &options),
  37. healthManager: health.NewHealthManager(fmt.Sprintf("%s-%s", probeNamePrefix, addr)),
  38. }
  39. }
  40. func (s *rpcServer) SetName(name string) {
  41. s.name = name
  42. s.baseRpcServer.SetName(name)
  43. }
  44. func (s *rpcServer) Start(register RegisterFn) error {
  45. lis, err := net.Listen("tcp", s.address)
  46. if err != nil {
  47. return err
  48. }
  49. unaryInterceptors := []grpc.UnaryServerInterceptor{
  50. serverinterceptors.UnaryTracingInterceptor,
  51. serverinterceptors.UnaryCrashInterceptor,
  52. serverinterceptors.UnaryStatInterceptor(s.metrics),
  53. serverinterceptors.UnaryPrometheusInterceptor,
  54. serverinterceptors.UnaryBreakerInterceptor,
  55. }
  56. unaryInterceptors = append(unaryInterceptors, s.unaryInterceptors...)
  57. streamInterceptors := []grpc.StreamServerInterceptor{
  58. serverinterceptors.StreamTracingInterceptor,
  59. serverinterceptors.StreamCrashInterceptor,
  60. serverinterceptors.StreamBreakerInterceptor,
  61. }
  62. streamInterceptors = append(streamInterceptors, s.streamInterceptors...)
  63. options := append(s.options, WithUnaryServerInterceptors(unaryInterceptors...),
  64. WithStreamServerInterceptors(streamInterceptors...))
  65. server := grpc.NewServer(options...)
  66. register(server)
  67. // register the health check service
  68. if s.health != nil {
  69. grpc_health_v1.RegisterHealthServer(server, s.health)
  70. s.health.Resume()
  71. }
  72. s.healthManager.MarkReady()
  73. health.AddProbe(s.healthManager)
  74. // we need to make sure all others are wrapped up,
  75. // so we do graceful stop at shutdown phase instead of wrap up phase
  76. waitForCalled := proc.AddWrapUpListener(func() {
  77. if s.health != nil {
  78. s.health.Shutdown()
  79. }
  80. server.GracefulStop()
  81. })
  82. defer waitForCalled()
  83. return server.Serve(lis)
  84. }
  85. // WithMetrics returns a func that sets metrics to a Server.
  86. func WithMetrics(metrics *stat.Metrics) ServerOption {
  87. return func(options *rpcServerOptions) {
  88. options.metrics = metrics
  89. }
  90. }
  91. // WithRpcHealth returns a func that sets rpc health switch to a Server.
  92. func WithRpcHealth(health bool) ServerOption {
  93. return func(options *rpcServerOptions) {
  94. options.health = health
  95. }
  96. }