duanfan1965 2015-12-20 21:46
浏览 76
已采纳

为什么这台HTTP服务器不会在Chrome 47中为每个请求生成一个goroutine?

Previously titled: How to spawn goroutine per HTTP request?

The code below is a simple HTTP server that echos the path back to the requester. I used it to test if the ListenAndServe method of the net/http package by default fires a goroutine to handle each request; which I discovered it doesn't. If I make three requests at the same time, the first takes 10 seconds to return, the second 20 (10 seconds after the first returns), and the third 30 seconds.

package main

import (
  "fmt"
  "net/http"
  "time"
)

func handler(w http.ResponseWriter, r *http.Request) {
  time.Sleep(10000 * time.Millisecond)
  fmt.Fprint(w, r.URL.Path)
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

Basically what I want is the main goroutine to listen for an HTTP connection, then pass the reading of the request and the response to a handler spawned in another goroutine.

Could someone point me in the right direction for accomplishing this? Preferably using the net/http package in go.

UPDATE 12/21/15 08:46 AM MST

I conducted the same exact test you did using my web browser (chrome 47), five requests at the root of localhost:8080, and the results were roughly:

1st: 10 seconds
2nd: 20 seconds
3rd: 30 seconds
4th: 36 seconds     
5th: 38 seconds

So, hopefully, the folks who would otherwise down-vote my question would understand my confusion and why I made the assumption I did. I have no idea why I got the results I did on the 4th and 5th request.

I ran the same test using curl and had the same results as @tomasz.

I'm using go1.2.1.

UPDATE 12/21/15 02:08 PM MST

Per @tomasz's suggestion below, I retitled this question from "How to spawn goroutine per HTTP request" to "Why isn't this go HTTP server spawning a goroutine per request in Chrome 47?"

  • 写回答

1条回答 默认 最新

  • dpc46827 2015-12-20 22:00
    关注

    All is good, your handler is run in a separate routine for each request. Take a look at the source code of http.Server.Serve method. The last line in accepting loop says:

    go c.serve()
    

    The problem is probably with your testing. If you check the behaviour through the multiple tabs in browser the requests for matching URLs are probably queued instead of running them simultaneously (i.e. your client is not using "routines", not the server).

    Try two different browsers or just use command line and, say, curl to test requests in parallel. For example (with some help from bash):

    $ for i in {1..5}; do time curl localhost:8080 &; done
    # after ignoring some mess...
    curl localhost:8080  0.00s user 0.00s system 0% cpu 10.013 total
    curl localhost:8080  0.00s user 0.00s system 0% cpu 10.014 total
    curl localhost:8080  0.00s user 0.00s system 0% cpu 10.012 total
    curl localhost:8080  0.00s user 0.00s system 0% cpu 10.019 total
    

    You server works like a charm.

    Update

    I can confirm this behaviour on Chrome 47, but also noticed you can open multiple tabs with, say, http://localhost:8080/test1, http://localhost:8080/test2 etc. and you will get expected results. That indicates there's indeed some queuing mechanism in Chrome for matching URLs.

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

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突