這是我之前的問題grpc middleware(interceptors) for metric
我想使用中間件。這就是我現在所擁有的。
func RequestTimeStream(mtr *metrics.Metrics) grpc.StreamServerInterceptor {
return grpc.StreamServerInterceptor(func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo,
handler grpc.StreamHandler) error {
beginTime := time.Now()
label, err := getLabel(info.FullMethod)
if err != nil {
return errors.Errorf("Unknown method name: %s", info.FullMethod)
}
defer mtr.RequestTime.With(metrics.MakeLabels(label)).Observe(time.Since(beginTime).Seconds())
if err := handler(srv, stream); err != nil {
return err
}
return nil
})
}
創建 grpc 服務器
streamInterceptors := grpc_middleware.ChainStreamServer(
middleware.RecoveryStream(logger, metrics.InternalGRPCPanicErrors),
identifyMdw.IdentifyStream,
middleware.AuthenticateStream(logger, metrics, authService),
middleware.LimitStream(logger, metrics, limiters),
middleware.RequestTimeStream(metrics),
)
opts := []grpc.ServerOption{grpc.UnaryInterceptor(unaryInterceptors), grpc.StreamInterceptor(streamInterceptors)}
grpcServer, err := ggrpc.NewServer(cfg.ServerConfig, opts...)
我的代碼作業不正常。指標太小了~30,000 納秒。
uj5u.com熱心網友回復:
假設我正確理解您的問題,我認為問題在于:
defer mtr.RequestTime.With(metrics.MakeLabels(label)).Observe(time.Since(beginTime).Seconds())
您似乎希望在函式退出時運行它并計算當時經過的時間。但是,根據語言規范:
每次執行“defer”陳述句時,函式值和呼叫的引數都會像往常一樣評估并重新保存,但不會呼叫實際的函式。
因此,當 defer 陳述句執行而不是在周圍函式退出(和 deferred 函式運行)時評估引數。這可以通過一個簡單的程式來演示:
beginTime := time.Now()
defer fmt.Println("defer", time.Since(beginTime).Seconds())
time.Sleep(2 * time.Second)
fmt.Println("non-defer", time.Since(beginTime).Seconds())
這將輸出如下內容:
non-defer 2
defer 0
有幾種可能的解決方案;最簡單的可能是使用閉包,例如
defer func() { fmt.Println("defer", time.Since(beginTime).Seconds()) }()
或者在你的情況下:
defer func() { mtr.RequestTime.With(metrics.MakeLabels(label)).Observe(time.Since(beginTime).Seconds())}()
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/393708.html
上一篇:在常量宣告中使用純函式
下一篇:Golang中的全域變數
