dongxuying7583
2016-11-15 04:08
浏览 258
已采纳

Golang HTTP处理程序-请求时间

I am trying to set a timer to count how much time is needed for my server to finish a request and I want the timer to stop after the last byte of the response is sent.

I found that the http server will only send the response after the handler function returns.

Is there any way to add a callback after the response is sent ?

Or is there a better way to count the time taken from the first byte of the request coming in till the last byte byte of the response is sent ?

图片转代码服务由CSDN问答提供 功能建议

我正在尝试设置一个计时器,以计算服务器完成请求所需的时间,我想要 发送响应的最后一个字节后计时器停止计时。

我发现http服务器仅在处理函数返回后才发送响应。

发送响应后,是否可以添加回调?

或者还有更好的方法来计算从请求的第一个字节进入到响应的最后一个字节发送所花费的时间吗?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongyan4157 2016-11-15 06:34
    已采纳

    The easier but not as accurate way to do it would be using a middleware to wrap your handler function.

    func timer(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            startTime := time.Now()
            h.ServeHTTP(w, r)
            duration := time.Now().Sub(startTime)
        })
    }
    

    Then

    http.Handle("/route",timer(yourHandler))
    

    This is more accurately the time taken to process the request and form the response and not the time between writes.


    If you absolutely need a more accurate duration then the parts of code you're looking to change reside in the net/http package.

    It would be around here.

    The highlighted line go c.serve(ctx) is where the the go routine for serving the request is spawned.

    for {
        rw, e := l.Accept()
        if e != nil {
            if ne, ok := e.(net.Error); ok && ne.Temporary() {
                if tempDelay == 0 {
                    tempDelay = 5 * time.Millisecond
                } else {
                    tempDelay *= 2
                }
                if max := 1 * time.Second; tempDelay > max {
                    tempDelay = max
                }
                srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
                time.Sleep(tempDelay)
                continue
            }
            return e
        }
        tempDelay = 0
    
        c := srv.newConn(rw)
        c.setState(c.rwc, StateNew) // before Serve can return
    
        go func(){
              startTime := time.Now()
              c.serve(ctx)
              duration := time.Now().Sub(startTime)
        }()
    
    }
    

    Note : The request actually gets written in the net.Conn somewhere inside l.Accept() but the highlighted point is the only place where we can have the approximate start time and end time within the same scope in the code.

    已采纳该答案
    打赏 评论

相关推荐 更多相似问题