diff --git a/go.mod b/go.mod index 50da1467..621b4234 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5 github.com/gogo/protobuf v1.3.2 github.com/golang/snappy v0.0.4 - github.com/grandcat/zeroconf v1.0.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru v1.0.2 github.com/jamiealquiza/tachymeter v2.0.0+incompatible @@ -60,6 +59,7 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grandcat/zeroconf v1.0.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/klauspost/reedsolomon v1.12.3 // indirect diff --git a/server/gateway.go b/server/gateway.go index 8d916260..49da1e6b 100644 --- a/server/gateway.go +++ b/server/gateway.go @@ -39,19 +39,6 @@ func (s *Server) startGateway(network string, ln net.Listener) net.Listener { go s.startJSONRPC2(jsonrpc2Ln) } - if s.EnableProfile { - // debugLn := m.Match(http1Path("/debug/")) - debugLn := m.Match(cmux.HTTP1Fast()) - vm := NewViewManager(debugLn, s) - go func() { - if err := vm.Start(); err != nil { - log.Errorf("start view manager failed: %v", err) - } - }() - - s.ViewManager = vm - } - if !s.DisableHTTPGateway { httpLn := m.Match(cmux.HTTP1Fast()) // X-RPCX-MessageID go s.startHTTP1APIGateway(httpLn) diff --git a/server/server.go b/server/server.go index 6a3ad231..26a176ad 100644 --- a/server/server.go +++ b/server/server.go @@ -20,7 +20,6 @@ import ( "sync/atomic" "time" - "github.com/jamiealquiza/tachymeter" "github.com/smallnest/rpcx/log" "github.com/smallnest/rpcx/protocol" "github.com/smallnest/rpcx/share" @@ -87,7 +86,6 @@ type Server struct { jsonrpcHTTPServer *http.Server DisableHTTPGateway bool // disable http invoke or not. DisableJSONRPC bool // disable json rpc or not. - EnableProfile bool // enable profile and statsview or not AsyncWrite bool // set true if your server only serves few clients pool WorkerPool @@ -119,7 +117,6 @@ type Server struct { handlerMsgNum int32 requestCount atomic.Uint64 - tachymeter *tachymeter.Tachymeter // HandleServiceError is used to get all service errors. You can use it write logs or others. HandleServiceError func(error) @@ -128,8 +125,6 @@ type Server struct { // If not set, it use err.Error() ServerErrorFunc func(res *protocol.Message, err error) string - ViewManager *ViewManager - // The server is started. Started chan struct{} } @@ -155,8 +150,6 @@ func NewServer(options ...OptionFn) *Server { s.options["TCPKeepAlivePeriod"] = 3 * time.Minute } - s.tachymeter = tachymeter.New(&tachymeter.Config{Size: 1000}) - return s } @@ -546,14 +539,6 @@ func (s *Server) processOneRequest(ctx *share.Context, req *protocol.Message, co atomic.AddInt32(&s.handlerMsgNum, 1) defer atomic.AddInt32(&s.handlerMsgNum, -1) - if s.EnableProfile && s.tachymeter != nil { - s.requestCount.Add(1) - start := time.Now() - defer func() { - s.tachymeter.AddTime(time.Since(start)) - }() - } - // 心跳请求,直接处理返回 if req.IsHeartbeat() { s.Plugins.DoHeartbeatRequest(ctx, req) diff --git a/server/statsview.go b/server/statsview.go deleted file mode 100644 index bb4f7426..00000000 --- a/server/statsview.go +++ /dev/null @@ -1,139 +0,0 @@ -//go:build !nostatsview -// +build !nostatsview - -package server - -import ( - "context" - "fmt" - "net" - "net/http" - "net/http/pprof" - "time" - - "github.com/go-echarts/go-echarts/v2/components" - "github.com/go-echarts/go-echarts/v2/templates" - "github.com/rs/cors" - "github.com/smallnest/statsview/statics" - "github.com/smallnest/statsview/viewer" -) - -// ViewManager -type ViewManager struct { - ln net.Listener - srv *http.Server - - Smgr *viewer.StatsMgr - Ctx context.Context - Cancel context.CancelFunc - Views []viewer.Viewer -} - -// Register registers views to the ViewManager -func (vm *ViewManager) Register(views ...viewer.Viewer) { - vm.Views = append(vm.Views, views...) -} - -// Start runs a http server and begin to collect metrics -func (vm *ViewManager) Start() error { - return vm.srv.Serve(vm.ln) -} - -// Stop shutdown the http server gracefully -func (vm *ViewManager) Stop() { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - vm.srv.Shutdown(ctx) - vm.Cancel() -} - -func init() { - templates.PageTpl = ` -{{- define "page" }} - - - {{- template "header" . }} - -

  rpcx profiler

- -
{{- range .Charts }} {{ template "base" . }} {{- end }}
- - -{{ end }} -` -} - -// NewViewManager creates a new ViewManager instance -func NewViewManager(ln net.Listener, s *Server) *ViewManager { - viewer.SetConfiguration(viewer.WithAddr(ln.Addr().String()), viewer.WithLinkAddr(ln.Addr().String())) - - page := components.NewPage() - page.PageTitle = "Statsview" - page.AssetsHost = fmt.Sprintf("http://%s/debug/statsview/statics/", viewer.LinkAddr()) - page.Assets.JSAssets.Add("jquery.min.js") - - srv := &http.Server{ - ReadTimeout: time.Minute, - WriteTimeout: time.Minute, - MaxHeaderBytes: 1 << 20, - } - - mgr := &ViewManager{ - ln: ln, - srv: srv, - } - - mgr.Ctx, mgr.Cancel = context.WithCancel(context.Background()) - mgr.Register( - viewer.NewGoroutinesViewer(), - viewer.NewHeapViewer(), - viewer.NewStackViewer(), - viewer.NewGCNumViewer(), - viewer.NewGCSizeViewer(), - viewer.NewGCCPUFractionViewer(), - NewHandlerViewer(s), - NewProcessTimeViewer(s), - NewRequestRateViewer(s), - ) - smgr := viewer.NewStatsMgr(mgr.Ctx) - for _, v := range mgr.Views { - v.SetStatsMgr(smgr) - } - - mux := http.NewServeMux() - mux.HandleFunc("/debug/pprof/", pprof.Index) - mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) - mux.HandleFunc("/debug/pprof/profile", pprof.Profile) - mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) - mux.HandleFunc("/debug/pprof/trace", pprof.Trace) - - for _, v := range mgr.Views { - page.AddCharts(v.View()) - mux.HandleFunc("/debug/statsview/view/"+v.Name(), v.Serve) - } - - mux.HandleFunc("/debug/statsview", func(w http.ResponseWriter, _ *http.Request) { - page.Render(w) - }) - - staticsPrev := "/debug/statsview/statics/" - mux.HandleFunc(staticsPrev+"echarts.min.js", func(w http.ResponseWriter, _ *http.Request) { - w.Write([]byte(statics.EchartJS)) - }) - - mux.HandleFunc(staticsPrev+"jquery.min.js", func(w http.ResponseWriter, _ *http.Request) { - w.Write([]byte(statics.JqueryJS)) - }) - - mux.HandleFunc(staticsPrev+"themes/westeros.js", func(w http.ResponseWriter, _ *http.Request) { - w.Write([]byte(statics.WesterosJS)) - }) - - mux.HandleFunc(staticsPrev+"themes/macarons.js", func(w http.ResponseWriter, _ *http.Request) { - w.Write([]byte(statics.MacaronsJS)) - }) - - mgr.srv.Handler = cors.AllowAll().Handler(mux) - - return mgr -} diff --git a/server/statsview_disabled.go b/server/statsview_disabled.go deleted file mode 100644 index f1db6c33..00000000 --- a/server/statsview_disabled.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build nostatsview -// +build nostatsview - -package server - -import ( - "net" -) - -// ViewManager -type ViewManager struct{} - -// Start runs a http server and begin to collect metrics -func (vm *ViewManager) Start() error { - return nil -} - -// Stop shutdown the http server gracefully -func (vm *ViewManager) Stop() { -} - -// NewViewManager creates a new ViewManager instance -func NewViewManager(ln net.Listener, s *Server) *ViewManager { - return new(ViewManager) -} diff --git a/server/statsview_handler_viewers.go b/server/statsview_handler_viewers.go deleted file mode 100644 index f08338dc..00000000 --- a/server/statsview_handler_viewers.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build !nostatsview -// +build !nostatsview - -package server - -import ( - "encoding/json" - "net/http" - "sync/atomic" - - "github.com/go-echarts/go-echarts/v2/charts" - "github.com/go-echarts/go-echarts/v2/opts" - "github.com/smallnest/statsview/viewer" -) - -const ( - // RPCXHandlerMetrics is the name of HandlerViewer - RPCXHandlerMetrics = "rpcx_handler" -) - -// HandlerViewer collects metrics of rpcx. -type HandlerViewer struct { - s *Server - smgr *viewer.StatsMgr - graph *charts.Line -} - -// NewHandlerViewer returns the HandlerViewer instance -func NewHandlerViewer(s *Server) viewer.Viewer { - graph := viewer.NewBasicView(RPCXHandlerMetrics) - graph.SetGlobalOptions( - charts.WithTitleOpts(opts.Title{Title: "RPCX Handler"}), - charts.WithYAxisOpts(opts.YAxis{Show: true, Name: "Requests"}), - ) - graph.AddSeries("Inflight", []opts.LineData{}) - - return &HandlerViewer{s: s, graph: graph} -} - -func (vr *HandlerViewer) SetStatsMgr(smgr *viewer.StatsMgr) { - vr.smgr = smgr -} - -func (vr *HandlerViewer) Name() string { - return RPCXHandlerMetrics -} - -func (vr *HandlerViewer) View() *charts.Line { - return vr.graph -} - -func (vr *HandlerViewer) Serve(w http.ResponseWriter, _ *http.Request) { - vr.smgr.Tick() - - metrics := viewer.Metrics{ - Values: []float64{float64(atomic.LoadInt32(&vr.s.handlerMsgNum))}, - Time: viewer.MemStats().T, - } - - bs, _ := json.Marshal(metrics) - w.Write(bs) -} diff --git a/server/statsview_processtime_viewers.go b/server/statsview_processtime_viewers.go deleted file mode 100644 index 7031caad..00000000 --- a/server/statsview_processtime_viewers.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build !nostatsview -// +build !nostatsview - -package server - -import ( - "encoding/json" - "net/http" - - "github.com/go-echarts/go-echarts/v2/charts" - "github.com/go-echarts/go-echarts/v2/opts" - "github.com/smallnest/statsview/viewer" -) - -const ( - // RPCXProcessTimeMetrics is the name of ProcessTimeViewer - RPCXProcessTimeMetrics = "rpcx_processtime" -) - -// ProcessTimeViewer collects metrics of rpcx. -type ProcessTimeViewer struct { - s *Server - smgr *viewer.StatsMgr - graph *charts.Line -} - -// NewProcessTimeViewer returns the ProcessTimeViewer instance -func NewProcessTimeViewer(s *Server) viewer.Viewer { - graph := viewer.NewBasicView(RPCXProcessTimeMetrics) - graph.SetGlobalOptions( - charts.WithTitleOpts(opts.Title{Title: "RPCX Process Time"}), - charts.WithYAxisOpts(opts.YAxis{Show: true, Name: "Time", AxisLabel: &opts.AxisLabel{Show: true, Formatter: "{value} ms"}}), - ) - graph.AddSeries("Avg", []opts.LineData{}) - graph.AddSeries("P99", []opts.LineData{}) - graph.AddSeries("Max", []opts.LineData{}) - graph.AddSeries("Min", []opts.LineData{}) - graph.AddSeries("Long 5%", []opts.LineData{}) - graph.AddSeries("Short 5%", []opts.LineData{}) - - return &ProcessTimeViewer{s: s, graph: graph} -} - -func (vr *ProcessTimeViewer) SetStatsMgr(smgr *viewer.StatsMgr) { - vr.smgr = smgr -} - -func (vr *ProcessTimeViewer) Name() string { - return RPCXProcessTimeMetrics -} - -func (vr *ProcessTimeViewer) View() *charts.Line { - return vr.graph -} - -func (vr *ProcessTimeViewer) Serve(w http.ResponseWriter, _ *http.Request) { - vr.smgr.Tick() - - calc := vr.s.tachymeter.Calc() - metrics := viewer.Metrics{ - Values: []float64{ - float64(calc.Time.Avg) / 1000000, - float64(calc.Time.P99) / 1000000, - float64(calc.Time.Max) / 1000000, - float64(calc.Time.Min) / 1000000, - float64(calc.Time.Long5p) / 1000000, - float64(calc.Time.Short5p) / 1000000, - }, - Time: viewer.MemStats().T, - } - - bs, _ := json.Marshal(metrics) - w.Write(bs) -} diff --git a/server/statsview_reqrate_viewers.go b/server/statsview_reqrate_viewers.go deleted file mode 100644 index 0aaf1488..00000000 --- a/server/statsview_reqrate_viewers.go +++ /dev/null @@ -1,92 +0,0 @@ -//go:build !nostatsview -// +build !nostatsview - -package server - -import ( - "encoding/json" - "net/http" - "time" - - "github.com/go-echarts/go-echarts/v2/charts" - "github.com/go-echarts/go-echarts/v2/opts" - "github.com/smallnest/statsview/viewer" -) - -const ( - // RPCXRequestRateMetrics is the name of RequestRateViewer - RPCXRequestRateMetrics = "rpcx_request_rate" -) - -// RequestRateViewer collects metrics of rpcx. -type RequestRateViewer struct { - lastTime time.Time - lastReq uint64 - s *Server - smgr *viewer.StatsMgr - graph *charts.Line -} - -// NewRequestRateViewer returns the RequestRateViewer instance -func NewRequestRateViewer(s *Server) viewer.Viewer { - graph := viewer.NewBasicView(RPCXRequestRateMetrics) - graph.SetGlobalOptions( - charts.WithTitleOpts(opts.Title{Title: "RPCX Request Rate"}), - charts.WithYAxisOpts(opts.YAxis{Show: true, Name: "reqs/sec"}), - ) - graph.AddSeries("Rate", []opts.LineData{}) - - return &RequestRateViewer{s: s, graph: graph} -} - -func (vr *RequestRateViewer) SetStatsMgr(smgr *viewer.StatsMgr) { - vr.smgr = smgr -} - -func (vr *RequestRateViewer) Name() string { - return RPCXRequestRateMetrics -} - -func (vr *RequestRateViewer) View() *charts.Line { - return vr.graph -} - -func (vr *RequestRateViewer) Serve(w http.ResponseWriter, _ *http.Request) { - vr.smgr.Tick() - - if vr.lastTime.IsZero() { - metrics := viewer.Metrics{ - Values: []float64{ - 0.0, - }, - Time: viewer.MemStats().T, - } - - bs, _ := json.Marshal(metrics) - w.Write(bs) - - vr.lastTime = time.Now() - vr.lastReq = vr.s.requestCount.Load() - - return - } - - now := time.Now() - d := now.Sub(vr.lastTime).Seconds() - currentReqCount := vr.s.requestCount.Load() - count := currentReqCount - vr.lastReq - rate := float64(count / uint64(d)) - - vr.lastTime = now - vr.lastReq = currentReqCount - - metrics := viewer.Metrics{ - Values: []float64{ - float64(rate), - }, - Time: viewer.MemStats().T, - } - - bs, _ := json.Marshal(metrics) - w.Write(bs) -}