You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-zero/zrpc/internal/rpcserver.go

143 lines
3.8 KiB
Go

4 years ago
package internal
4 years ago
import (
"fmt"
4 years ago
"net"
"github.com/zeromicro/go-zero/core/proc"
"github.com/zeromicro/go-zero/core/stat"
"github.com/zeromicro/go-zero/internal/health"
"github.com/zeromicro/go-zero/zrpc/internal/serverinterceptors"
"google.golang.org/grpc"
"google.golang.org/grpc/health/grpc_health_v1"
4 years ago
)
const probeNamePrefix = "zrpc"
4 years ago
type (
// ServerOption defines the method to customize a rpcServerOptions.
4 years ago
ServerOption func(options *rpcServerOptions)
rpcServerOptions struct {
metrics *stat.Metrics
health bool
4 years ago
}
rpcServer struct {
*baseRpcServer
name string
middlewares ServerMiddlewaresConf
healthManager health.Probe
4 years ago
}
)
// NewRpcServer returns a Server.
func NewRpcServer(addr string, middlewares ServerMiddlewaresConf, opts ...ServerOption) Server {
4 years ago
var options rpcServerOptions
for _, opt := range opts {
opt(&options)
}
if options.metrics == nil {
options.metrics = stat.NewMetrics(addr)
4 years ago
}
return &rpcServer{
baseRpcServer: newBaseRpcServer(addr, &options),
middlewares: middlewares,
healthManager: health.NewHealthManager(fmt.Sprintf("%s-%s", probeNamePrefix, addr)),
4 years ago
}
}
func (s *rpcServer) SetName(name string) {
s.name = name
4 years ago
s.baseRpcServer.SetName(name)
}
func (s *rpcServer) Start(register RegisterFn) error {
lis, err := net.Listen("tcp", s.address)
if err != nil {
return err
}
unaryInterceptors := s.buildUnaryInterceptors()
4 years ago
unaryInterceptors = append(unaryInterceptors, s.unaryInterceptors...)
streamInterceptors := s.buildStreamInterceptors()
4 years ago
streamInterceptors = append(streamInterceptors, s.streamInterceptors...)
options := append(s.options, grpc.ChainUnaryInterceptor(unaryInterceptors...),
grpc.ChainStreamInterceptor(streamInterceptors...))
4 years ago
server := grpc.NewServer(options...)
register(server)
// register the health check service
if s.health != nil {
grpc_health_v1.RegisterHealthServer(server, s.health)
s.health.Resume()
}
s.healthManager.MarkReady()
health.AddProbe(s.healthManager)
// we need to make sure all others are wrapped up,
4 years ago
// so we do graceful stop at shutdown phase instead of wrap up phase
waitForCalled := proc.AddWrapUpListener(func() {
if s.health != nil {
s.health.Shutdown()
}
4 years ago
server.GracefulStop()
})
defer waitForCalled()
4 years ago
return server.Serve(lis)
4 years ago
}
func (s *rpcServer) buildStreamInterceptors() []grpc.StreamServerInterceptor {
var interceptors []grpc.StreamServerInterceptor
if s.middlewares.Trace {
interceptors = append(interceptors, serverinterceptors.StreamTracingInterceptor)
}
if s.middlewares.Recover {
interceptors = append(interceptors, serverinterceptors.StreamRecoverInterceptor)
}
if s.middlewares.Breaker {
interceptors = append(interceptors, serverinterceptors.StreamBreakerInterceptor)
}
return interceptors
}
func (s *rpcServer) buildUnaryInterceptors() []grpc.UnaryServerInterceptor {
var interceptors []grpc.UnaryServerInterceptor
if s.middlewares.Trace {
interceptors = append(interceptors, serverinterceptors.UnaryTracingInterceptor)
}
if s.middlewares.Recover {
interceptors = append(interceptors, serverinterceptors.UnaryRecoverInterceptor)
}
if s.middlewares.Stat {
interceptors = append(interceptors, serverinterceptors.UnaryStatInterceptor(s.metrics))
}
if s.middlewares.Prometheus {
interceptors = append(interceptors, serverinterceptors.UnaryPrometheusInterceptor)
}
if s.middlewares.Breaker {
interceptors = append(interceptors, serverinterceptors.UnaryBreakerInterceptor)
}
return interceptors
}
// WithMetrics returns a func that sets metrics to a Server.
4 years ago
func WithMetrics(metrics *stat.Metrics) ServerOption {
return func(options *rpcServerOptions) {
options.metrics = metrics
}
}
// WithRpcHealth returns a func that sets rpc health switch to a Server.
func WithRpcHealth(health bool) ServerOption {
return func(options *rpcServerOptions) {
options.health = health
}
}