diff --git a/Makefile b/Makefile index 24b4963..7ba6c1e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#SHELL := /bin/bash +SHELL := /bin/bash PROJECT_NAME := "github.com/zhufuyi/sponge" PKG := "$(PROJECT_NAME)" diff --git a/README.md b/README.md index 1c4612b..c4dab11 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ Features : - Documentation [swagger](https://github.com/swaggo/swag) - Authorization [jwt](https://github.com/golang-jwt/jwt) - Validator [validator](https://github.com/go-playground/validator) -- Rate limiter [aegis](https://github.com/go-kratos/aegis) -- Circuit Breaker [aegis](https://github.com/go-kratos/aegis) +- Rate limiter [ratelimit](pkg/shield/ratelimit) +- Circuit Breaker [circuitbreaker](pkg/shield/circuitbreaker) - Tracing [opentelemetry](https://go.opentelemetry.io/otel) - Monitoring [prometheus](https://github.com/prometheus/client_golang/prometheus), [grafana](https://github.com/grafana/grafana) - Service registry and discovery [etcd](https://github.com/etcd-io/etcd), [consul](https://github.com/hashicorp/consul), [nacos](https://github.com/alibaba/) diff --git a/cmd/serverNameExample/initial/initApp.go b/cmd/serverNameExample/initial/initApp.go index 87bae3c..ec12b4a 100644 --- a/cmd/serverNameExample/initial/initApp.go +++ b/cmd/serverNameExample/initial/initApp.go @@ -3,13 +3,15 @@ package initial import ( "flag" "fmt" + "strconv" + "github.com/zhufuyi/sponge/configs" "github.com/zhufuyi/sponge/internal/config" "github.com/zhufuyi/sponge/internal/model" - "strconv" "github.com/zhufuyi/sponge/pkg/logger" "github.com/zhufuyi/sponge/pkg/nacoscli" + "github.com/zhufuyi/sponge/pkg/stat" "github.com/zhufuyi/sponge/pkg/tracer" "github.com/jinzhu/copier" @@ -48,6 +50,11 @@ func Config() { cfg.App.TracingSamplingRate, ) } + + // 初始化打印系统和进程资源 + if cfg.App.EnableStat { + stat.Init(stat.WithLog(logger.Get())) + } } // 初始化配置 diff --git a/cmd/serverNameExample/main.go b/cmd/serverNameExample/main.go index e045cec..0235dc0 100644 --- a/cmd/serverNameExample/main.go +++ b/cmd/serverNameExample/main.go @@ -12,11 +12,10 @@ import ( // @version v0.0.0 // @host localhost:8080 func main() { - initial.Config() servers := initial.RegisterServers() closes := initial.RegisterClose(servers) - initial.Init() + a := app.New(servers, closes) a.Run() } diff --git a/cmd/serverNameExample_grpcExample/initial/initApp.go b/cmd/serverNameExample_grpcExample/initial/initApp.go index 7c166b5..ec12b4a 100644 --- a/cmd/serverNameExample_grpcExample/initial/initApp.go +++ b/cmd/serverNameExample_grpcExample/initial/initApp.go @@ -11,6 +11,7 @@ import ( "github.com/zhufuyi/sponge/pkg/logger" "github.com/zhufuyi/sponge/pkg/nacoscli" + "github.com/zhufuyi/sponge/pkg/stat" "github.com/zhufuyi/sponge/pkg/tracer" "github.com/jinzhu/copier" @@ -49,6 +50,11 @@ func Config() { cfg.App.TracingSamplingRate, ) } + + // 初始化打印系统和进程资源 + if cfg.App.EnableStat { + stat.Init(stat.WithLog(logger.Get())) + } } // 初始化配置 diff --git a/cmd/serverNameExample_gwExample/initial/initApp.go b/cmd/serverNameExample_gwExample/initial/initApp.go index 91e6275..9adf2e9 100644 --- a/cmd/serverNameExample_gwExample/initial/initApp.go +++ b/cmd/serverNameExample_gwExample/initial/initApp.go @@ -11,6 +11,7 @@ import ( "github.com/zhufuyi/sponge/pkg/logger" "github.com/zhufuyi/sponge/pkg/nacoscli" + "github.com/zhufuyi/sponge/pkg/stat" "github.com/zhufuyi/sponge/pkg/tracer" "github.com/jinzhu/copier" @@ -48,6 +49,11 @@ func Config() { // 初始化rpc服务连接 rpcclient.NewServerNameExampleRPCConn() + + // 初始化打印系统和进程资源 + if cfg.App.EnableStat { + stat.Init(stat.WithLog(logger.Get())) + } } // 初始化配置 diff --git a/cmd/serverNameExample_httpExample/initial/initApp.go b/cmd/serverNameExample_httpExample/initial/initApp.go index 7c166b5..ec12b4a 100644 --- a/cmd/serverNameExample_httpExample/initial/initApp.go +++ b/cmd/serverNameExample_httpExample/initial/initApp.go @@ -11,6 +11,7 @@ import ( "github.com/zhufuyi/sponge/pkg/logger" "github.com/zhufuyi/sponge/pkg/nacoscli" + "github.com/zhufuyi/sponge/pkg/stat" "github.com/zhufuyi/sponge/pkg/tracer" "github.com/jinzhu/copier" @@ -49,6 +50,11 @@ func Config() { cfg.App.TracingSamplingRate, ) } + + // 初始化打印系统和进程资源 + if cfg.App.EnableStat { + stat.Init(stat.WithLog(logger.Get())) + } } // 初始化配置 diff --git a/configs/serverNameExample.yml b/configs/serverNameExample.yml index 0cff4f3..d083c00 100644 --- a/configs/serverNameExample.yml +++ b/configs/serverNameExample.yml @@ -6,7 +6,8 @@ app: env: "dev" # 运行环境,dev:开发环境,prod:生产环境,test:测试环境 version: "v0.0.0" # 版本 host: "192.168.3.27" # 主机名称或ip - enablePprof: false # 是否开启性能分析功能,true:开启,false:关闭 + enablePprof: true # 是否开启性能分析功能,true:开启,false:关闭 + enableStat: true # 是否开启打印统计信息,true:开启,false:关闭 enableMetrics: true # 是否开启指标采集,true:开启,false:关闭 enableLimit: false # 是否开启限流(自适应),true:开启,false:关闭 enableCircuitBreaker: false # 是否开启熔断(自适应),true:开启,false:关闭 @@ -26,8 +27,7 @@ http: # grpc server 设置 grpc: port: 8282 # rpc监听端口 - metricsPort: 8283 # 获取指标http端口 - pprofPort: 8284 # pprof的http端口 + httpPort: 8283 # 获取pprof和监控指标http端口 readTimeout: 3 # 读超时,单位(秒) writeTimeout: 3 # 写超时,单位(秒) diff --git a/go.mod b/go.mod index 6f9dca1..7fc6140 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,11 @@ require ( github.com/bojand/ghz v0.110.0 github.com/dgraph-io/ristretto v0.1.0 github.com/envoyproxy/protoc-gen-validate v0.6.2 + github.com/felixge/fgprof v0.9.3 github.com/fsnotify/fsnotify v1.5.4 github.com/gin-contrib/cors v1.3.1 github.com/gin-contrib/pprof v1.4.0 github.com/gin-gonic/gin v1.8.1 - github.com/go-kratos/aegis v0.1.3 github.com/go-playground/validator/v10 v10.11.0 github.com/go-redis/redis/extra/redisotel v0.3.0 github.com/go-redis/redis/v8 v8.11.5 @@ -30,6 +30,7 @@ require ( github.com/nacos-group/nacos-sdk-go/v2 v2.1.0 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/prometheus/client_golang v1.13.0 + github.com/shirou/gopsutil/v3 v3.21.8 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 @@ -101,6 +102,7 @@ require ( github.com/golang/glog v1.0.0 // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.2.0 // indirect @@ -137,7 +139,6 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - github.com/shirou/gopsutil/v3 v3.21.8 // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect diff --git a/go.sum b/go.sum index 27106a6..39477ae 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= +github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -199,8 +201,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-kratos/aegis v0.1.3 h1:hXw/iO51ofO0hSRBijbmGNidthfAo9Oc/PZSl/lRCxk= -github.com/go-kratos/aegis v0.1.3/go.mod h1:jYeSQ3Gesba478zEnujOiG5QdsyF3Xk/8owFUeKcHxw= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -327,6 +327,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y= +github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -400,6 +402,7 @@ github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -939,6 +942,7 @@ golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/config/serverNameExample.go b/internal/config/serverNameExample.go index bb3061b..c647966 100644 --- a/internal/config/serverNameExample.go +++ b/internal/config/serverNameExample.go @@ -62,6 +62,7 @@ type App struct { EnableLimit bool `yaml:"enableLimit" json:"enableLimit"` EnableMetrics bool `yaml:"enableMetrics" json:"enableMetrics"` EnablePprof bool `yaml:"enablePprof" json:"enablePprof"` + EnableStat bool `yaml:"enableStat" json:"enableStat"` EnableTracing bool `yaml:"enableTracing" json:"enableTracing"` Env string `yaml:"env" json:"env"` Host string `yaml:"host" json:"host"` @@ -93,6 +94,13 @@ type Logger struct { Level string `yaml:"level" json:"level"` } +type Grpc struct { + HTTPPort int `yaml:"httpPort" json:"httpPort"` + Port int `yaml:"port" json:"port"` + ReadTimeout int `yaml:"readTimeout" json:"readTimeout"` + WriteTimeout int `yaml:"writeTimeout" json:"writeTimeout"` +} + type GrpcClient struct { Host string `yaml:"host" json:"host"` Name string `yaml:"name" json:"name"` @@ -106,14 +114,6 @@ type NacosRd struct { Port int `yaml:"port" json:"port"` } -type Grpc struct { - MetricsPort int `yaml:"metricsPort" json:"metricsPort"` - Port int `yaml:"port" json:"port"` - PprofPort int `yaml:"pprofPort" json:"pprofPort"` - ReadTimeout int `yaml:"readTimeout" json:"readTimeout"` - WriteTimeout int `yaml:"writeTimeout" json:"writeTimeout"` -} - type HTTP struct { Port int `yaml:"port" json:"port"` ReadTimeout int `yaml:"readTimeout" json:"readTimeout"` diff --git a/internal/routers/routers.go b/internal/routers/routers.go index 0c2a6c1..5845a06 100644 --- a/internal/routers/routers.go +++ b/internal/routers/routers.go @@ -12,6 +12,7 @@ import ( "github.com/zhufuyi/sponge/pkg/gin/validator" "github.com/zhufuyi/sponge/pkg/logger" + "github.com/felixge/fgprof" "github.com/gin-contrib/pprof" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" @@ -65,6 +66,8 @@ func NewRouter() *gin.Engine { // profile 性能分析 if config.Get().App.EnablePprof { + // https://github.com/felixge/fgprof + r.GET("/debug/fgprof", gin.WrapH(fgprof.Handler())) pprof.Register(r) } diff --git a/internal/routers/routers_gwExample.go b/internal/routers/routers_gwExample.go new file mode 100644 index 0000000..47cfaae --- /dev/null +++ b/internal/routers/routers_gwExample.go @@ -0,0 +1,87 @@ +package routers + +import ( + "net/http" + + "github.com/zhufuyi/sponge/docs" + "github.com/zhufuyi/sponge/internal/config" + + "github.com/zhufuyi/sponge/pkg/gin/handlerfunc" + "github.com/zhufuyi/sponge/pkg/gin/middleware" + "github.com/zhufuyi/sponge/pkg/gin/middleware/metrics" + "github.com/zhufuyi/sponge/pkg/gin/swagger" + "github.com/zhufuyi/sponge/pkg/gin/validator" + "github.com/zhufuyi/sponge/pkg/logger" + + "github.com/felixge/fgprof" + "github.com/gin-contrib/pprof" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +var ( + rootRouterFns []func(engine *gin.Engine) // 根路由组,rpc gateway使用 +) + +// NewRouter_gwExample 创建一个路由 +func NewRouter_gwExample() *gin.Engine { //nolint + r := gin.New() + + r.Use(gin.Recovery()) + r.Use(middleware.Cors()) + + // request id 中间件 + r.Use(middleware.RequestID()) + + // logger 中间件 + r.Use(middleware.Logging( + middleware.WithLog(logger.Get()), + middleware.WithRequestIDFromContext(), + middleware.WithIgnoreRoutes("/metrics"), // 忽略路由 + )) + + // metrics 中间件 + if config.Get().App.EnableMetrics { + r.Use(metrics.Metrics(r, + //metrics.WithMetricsPath("/metrics"), // 默认是 /metrics + metrics.WithIgnoreStatusCodes(http.StatusNotFound), // 忽略404状态码 + )) + } + + // limit 中间件 + if config.Get().App.EnableLimit { + r.Use(middleware.RateLimit()) + } + + // circuit breaker 中间件 + if config.Get().App.EnableCircuitBreaker { + r.Use(middleware.CircuitBreaker()) + } + + // trace 中间件 + if config.Get().App.EnableTracing { + r.Use(middleware.Tracing(config.Get().App.Name)) + } + + // profile 性能分析 + if config.Get().App.EnablePprof { + // https://github.com/felixge/fgprof + r.GET("/debug/fgprof", gin.WrapH(fgprof.Handler())) + pprof.Register(r) + } + + // 校验器 + binding.Validator = validator.Init() + + r.GET("/health", handlerfunc.CheckHealth) + r.GET("/ping", handlerfunc.Ping) + + swagger.CustomRouter(r, "apis", docs.ApiDocs) + + // 注册/前缀路由组 + for _, fn := range rootRouterFns { + fn(r) + } + + return r +} diff --git a/internal/routers/routers_gwExample_test.go b/internal/routers/routers_gwExample_test.go new file mode 100644 index 0000000..bc836f6 --- /dev/null +++ b/internal/routers/routers_gwExample_test.go @@ -0,0 +1,57 @@ +package routers + +import ( + "context" + "testing" + + serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1" + "github.com/zhufuyi/sponge/configs" + "github.com/zhufuyi/sponge/internal/config" + + "github.com/gin-gonic/gin" +) + +func TestNewRouter_gwExample(t *testing.T) { + err := config.Init(configs.Path("serverNameExample.yml")) + if err != nil { + t.Fatal(err) + } + + config.Get().App.EnableMetrics = true + config.Get().App.EnableTracing = true + config.Get().App.EnablePprof = true + config.Get().App.EnableLimit = true + config.Get().App.EnableCircuitBreaker = true + + gin.SetMode(gin.ReleaseMode) + r := NewRouter_gwExample() + + defer func() { recover() }() + userExampleRouter_gwExample(r, &mockGw{}) +} + +type mockGw struct{} + +func (m mockGw) Create(ctx context.Context, req *serverNameExampleV1.CreateUserExampleRequest) (*serverNameExampleV1.CreateUserExampleReply, error) { + return nil, nil +} + +func (m mockGw) DeleteByID(ctx context.Context, req *serverNameExampleV1.DeleteUserExampleByIDRequest) (*serverNameExampleV1.DeleteUserExampleByIDReply, error) { + return nil, nil +} + +func (m mockGw) GetByID(ctx context.Context, req *serverNameExampleV1.GetUserExampleByIDRequest) (*serverNameExampleV1.GetUserExampleByIDReply, error) { + return nil, nil +} + +func (m mockGw) List(ctx context.Context, req *serverNameExampleV1.ListUserExampleRequest) (*serverNameExampleV1.ListUserExampleReply, error) { + return nil, nil +} + +func (m mockGw) ListByIDs(ctx context.Context, req *serverNameExampleV1.ListUserExampleByIDsRequest) (*serverNameExampleV1.ListUserExampleByIDsReply, error) { + return nil, nil +} + +func (m mockGw) UpdateByID(ctx context.Context, req *serverNameExampleV1.UpdateUserExampleByIDRequest) (*serverNameExampleV1.UpdateUserExampleByIDReply, error) { + return nil, nil +} diff --git a/internal/server/grpc.go b/internal/server/grpc.go index 1415d45..bd9e711 100644 --- a/internal/server/grpc.go +++ b/internal/server/grpc.go @@ -2,11 +2,9 @@ package server import ( "context" - "errors" "fmt" "net" "net/http" - "net/http/pprof" "time" "github.com/zhufuyi/sponge/internal/config" @@ -16,6 +14,7 @@ import ( "github.com/zhufuyi/sponge/pkg/grpc/interceptor" "github.com/zhufuyi/sponge/pkg/grpc/metrics" "github.com/zhufuyi/sponge/pkg/logger" + "github.com/zhufuyi/sponge/pkg/prof" "github.com/zhufuyi/sponge/pkg/servicerd/registry" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" @@ -23,16 +22,15 @@ import ( ) var _ app.IServer = (*grpcServer)(nil) -var _ = pprof.Cmdline type grpcServer struct { addr string server *grpc.Server listen net.Listener - metricsHTTPServer *http.Server + mux *http.ServeMux + httpServer *http.Server metricsHTTPServerFunc func() error - pprofHTTPServerFunc func() error iRegistry registry.Registry instance *registry.ServiceInstance @@ -53,10 +51,18 @@ func (s *grpcServer) Start() error { } } - if s.pprofHTTPServerFunc != nil { - if err := s.pprofHTTPServerFunc(); err != nil { - return err + if s.mux != nil { // 如果启用pprof或metrics任何一个,都会启动http服务 + addr := fmt.Sprintf(":%d", config.Get().Grpc.HTTPPort) + httpSrv := &http.Server{ + Addr: addr, + Handler: s.mux, } + go func() { + fmt.Printf("http address of pprof and metrics %s\n", addr) + if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + panic("listen and serve error: " + err.Error()) + } + }() } if err := s.server.Serve(s.listen); err != nil { // block @@ -79,9 +85,9 @@ func (s *grpcServer) Stop() error { s.server.GracefulStop() - if s.metricsHTTPServer != nil { + if s.httpServer != nil { ctx, _ := context.WithTimeout(context.Background(), 3*time.Second) //nolint - if err := s.metricsHTTPServer.Shutdown(ctx); err != nil { + if err := s.httpServer.Shutdown(ctx); err != nil { return err } } @@ -113,7 +119,7 @@ func (s *grpcServer) serverOptions() []grpc.ServerOption { // metrics interceptor if config.Get().App.EnableMetrics { unaryServerInterceptors = append(unaryServerInterceptors, interceptor.UnaryServerMetrics()) - s.metricsHTTPServerFunc = s.metricsServer() + s.metricsHTTPServerFunc = s.registerHTTPMetrics() } // limit interceptor @@ -139,29 +145,21 @@ func (s *grpcServer) serverOptions() []grpc.ServerOption { return options } -func (s *grpcServer) metricsServer() func() error { +func (s *grpcServer) registerHTTPMetrics() func() error { return func() error { - if s == nil || s.server == nil { - return errors.New("grpc server is nil") + if s.mux == nil { + s.mux = http.NewServeMux() } - promAddr := fmt.Sprintf(":%d", config.Get().Grpc.MetricsPort) - fmt.Printf("grpc metrics address %s\n", promAddr) - s.metricsHTTPServer = metrics.GoHTTPService(promAddr, s.server) + metrics.Register(s.mux, s.server) return nil } } -func (s *grpcServer) pprofServer() func() error { - return func() error { - pprofAddr := fmt.Sprintf(":%d", config.Get().Grpc.PprofPort) - fmt.Printf("grpc pprof address %s\n", pprofAddr) - go func() { - if err := http.ListenAndServe(pprofAddr, nil); err != nil { // default route is /debug/pprof - panic("listen and serve error: " + err.Error()) - } - }() - return nil +func (s *grpcServer) registerHTTPPprof() { + if s.mux == nil { + s.mux = http.NewServeMux() } + prof.Register(s.mux) } // NewGRPCServer creates a new grpc server @@ -175,7 +173,7 @@ func NewGRPCServer(addr string, opts ...GrpcOption) app.IServer { instance: o.instance, } if config.Get().App.EnablePprof { - s.pprofHTTPServerFunc = s.pprofServer() + s.registerHTTPPprof() } s.listen, err = net.Listen("tcp", addr) diff --git a/internal/server/grpc_test.go b/internal/server/grpc_test.go index ca848b6..fcb781c 100644 --- a/internal/server/grpc_test.go +++ b/internal/server/grpc_test.go @@ -70,7 +70,8 @@ func TestGRPCServerMock(t *testing.T) { iRegistry: o.iRegistry, instance: o.instance, } - s.pprofHTTPServerFunc = s.pprofServer() + //s.registerHTTPPprof() + //s.metricsHTTPServerFunc = s.registerHTTPMetrics() s.listen, err = net.Listen("tcp", addr) if err != nil { t.Fatal(err) diff --git a/internal/server/http.go b/internal/server/http.go index d379b9c..869f292 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -70,7 +70,7 @@ func NewHTTPServer(addr string, opts ...HTTPOption) app.IServer { gin.SetMode(gin.DebugMode) } - //router := routers.NewRouter() + // router := routers.NewRouter() router := routers.NewRouter_gwExample() server := &http.Server{ Addr: addr,