為什么 Golog包會減慢我的 http API 的速度?有那么慢嗎?這是我使用httprouter 而不記錄的路由器示例:package mainimport ( "fmt" "log" "net/http" "time" "github.com/julienschmidt/httprouter")func main() { handler := httprouter.New() handler.GET("/hello", f) http.ListenAndServe(fmt.Sprintf(":%d", 8080), handler)}func f(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "world")}使用wrk對該端點進行基準測試,我得到了這個:$ wrk -t1 -d1s -c100 http://localhost:8080/helloRunning 1s test @ http://localhost:8080/hello 1 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.15ms 197.55us 2.84ms 80.02% Req/Sec 84.58k 6.15k 99.01k 80.00% 83904 requests in 1.01s, 9.68MB readRequests/sec: 83380.37Transfer/sec: 9.62MB當我添加中間件進行日志記錄時:package mainimport ( "fmt" "log" "net/http" "time" "github.com/julienschmidt/httprouter")func main() { handler := httprouter.New() handler.GET("/hello", logger(f)) fmt.Println("httprouter") http.ListenAndServe(fmt.Sprintf(":%d", 8080), handler)}func logger(next httprouter.Handle) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { start := time.Now() next(w, r, ps) elapsed := time.Since(start) log.Printf("%s | %s | %s | %d\n", time.Now().Format(time.RFC3339), r.Method, r.URL.Path, elapsed) }}func f(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "world")}它被減慢到 4 倍:$ wrk -t1 -d1s -c100 http://localhost:8080/helloRunning 1s test @ http://localhost:8080/hello 1 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 5.25ms 4.34ms 26.47ms 60.23% Req/Sec 20.51k 2.19k 24.28k 70.00% 20449 requests in 1.01s, 2.36MB readRequests/sec: 20330.66Transfer/sec: 2.35MB
1 回答

慕娘9325324
TA貢獻1783條經驗 獲得超4個贊
該答案總結了對該問題的評論。
使用緩沖 io
從 goroutine 寫入以減少來自其他日志記錄 goroutine 的阻塞。
這是代碼:
type writer chan []byte
func (w writer) Write(p []byte) (int, error) {
w <- append(([]byte)(nil), p...)
return len(p), nil
}
func writePump(w writer) {
bw := bufio.NewWriter(os.Stderr)
for p := range w {
bw.Write(p)
// Slurp up buffered messages in flush. This ensures
// timely output.
n := len(w)
for i := 0; i < n; i++ {
bw.Write(<-w)
}
bw.Flush()
}
}
設置如下:
w := make(writer, 16) // adjust capacity to meet your needs
go writePump(w)
log.SetOutput(w)
- 1 回答
- 0 關注
- 111 瀏覽
添加回答
舉報
0/150
提交
取消