在 golang Web 服務器中,我想測量某個 http 控制器所用的時間。我time.Now()在呼叫控制器函式之前呼叫,time.Since()在控制器函式回傳之后呼叫。但是如果它有需要 1 秒的長遠程 io 請求,或者行程受到限制,或者控制器與 goroutines 并行 - 那么那個時間將不是我想要的。
如果我們假設類比 bashtime命令 - 那么我有real時間使用這種技術:
time go build
real 0m5,204s
user 0m12,012s
sys 0m2,043s
如何衡量user和sys時間的函式運行(最好為一個夠程加上其分叉兒)在golang程式(最好用標準軟體包)?
這是我的分析器實作。我如何使用每個 goroutine 的 sys 和用戶時間來擴展它?
const HeaderCost = "Cost"
// Timed middleware will set Cost header in http response
func Timed(h http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(&responseWriterWithTimer{
ResponseWriter: w,
headerWritten: false,
startedAt: time.Now(),
}, r)
})
}
type responseWriterWithTimer struct {
http.ResponseWriter
headerWritten bool
startedAt time.Time
}
func (w *responseWriterWithTimer) WriteHeader(statusCode int) {
w.Header().Set(
HeaderCost,
strconv.FormatFloat(
time.Since(w.startedAt).Seconds(),
'g',
64,
64,
),
)
w.ResponseWriter.WriteHeader(statusCode)
w.headerWritten = true
}
func (w *responseWriterWithTimer) Write(b []byte) (int, error) {
if !w.headerWritten {
w.WriteHeader(http.StatusOK)
}
return w.ResponseWriter.Write(b)
}
uj5u.com熱心網友回復:
如果你想在運行時進行基本的檢測,你可以包裝你的處理程式來測量它們的執行時間:
func perfMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t := time.Now()
h.ServeHTTP(w, r)
log.Printf("handler took %s", time.Since(t))
})
}
您可以使用expvar. 除此之外,還有許多可用于 Go 的儀器/遙測/APM 庫(如果您需要的話),以及諸如 TICK 堆疊、Datadog 等指標管理解決方案。
至于real,user和sys由輸出資料time,這些是不完全適用于插裝POSIX措施轉到HTTP處理程式(或在運行時代碼的任何其它單元),用于有許多原因:
- goroutine 沒有父子關系;所有人都是平等的同齡人,因此沒有衡量您的處理程式的“孩子”所花費的時間的指標。
- 大多數 I/O 是在 stdlib 中處理的,它沒有被檢測到這個級別(并且這個級別的檢測本身會對性能產生不可忽視的影響)
當然,您可以單獨對每件作品進行樂器演奏,這通常更有用;例如,檢測您的 HTTP 處理程式以及發出自己的外部請求的任何代碼,以測量每個組件的性能。從中您可以分析資料并更清楚地了解需要花費的時間,以便解決您發現的任何性能問題。
uj5u.com熱心網友回復:
如果您想孤立地衡量某事,基準可能正是您所追求的。
如果您嘗試測量 a http.Handler,您可以使用httptest.NewRecorder和httptest.NewRequest創建一個新的回應撰寫器和請求物件,然后直接在您的基準測驗中呼叫處理程式。
func BenchmnarkHttpHandler(b*testing.B) {
req := httptest.NewRequest("GET", "/foo", nil)
myHandler := thingtotest.Handler{}
for n := 0; n < b.N; n {
myHandler.ServeHTTP(httptest.NewRecorder(), req);
}
}
uj5u.com熱心網友回復:
如何測量函式運行的用戶和系統時間
你不能。這種區別對于 Go 函式來說是無法觀察到的。
(但老實說:測量它們沒有實際用處,也沒有多大意義。這聽起來像是 XY 問題。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/358739.html
