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

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 ?

  • 写回答

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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线