rpcserver.go 2.7 KB

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