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

以前的标题:如何为每个 HTTP 请求生成 goroutine?


下面的代码是一个简单的 HTTP 服务器,它将路径回显给请求者。我用它来测试包的ListenAndServe方法是否net/http默认触发一个 goroutine 来处理每个请求;我发现它没有。如果我同时发出三个请求,第一个需要 10 秒返回,第二个需要 20(第一个返回后 10 秒),第三个需要 30 秒。


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)

}

基本上我想要的是主 goroutine 来监听 HTTP 连接,然后将请求的读取和响应传递给另一个 goroutine 中产生的处理程序。


有人可以为我指出实现这一目标的正确方向吗?最好net/http在 go 中使用包。


更新 12/21/15 08:46 AM MST


我进行了与您使用 Web 浏览器 (chrome 47) 所做的完全相同的测试,在 localhost:8080 的根目录下进行了五个请求,结果大致如下:


1st: 10 seconds

2nd: 20 seconds

3rd: 30 seconds

4th: 36 seconds     

5th: 38 seconds

因此,希望那些否则会否决我的问题的人会理解我的困惑以及我为什么做出这样的假设。我不知道为什么我得到了我在第 4 次和第 5 次请求中所做的结果。


我使用 curl 运行了相同的测试,结果与@tomasz 相同。


我正在使用go1.2.1.




猛跑小猪
浏览 149回答 1
1回答

慕雪6442864

一切都很好,您的处理程序针对每个请求在单独的例程中运行。看一下http.Server.Serve方法的源代码。接受循环的最后一行说:go c.serve()问题可能出在您的测试上。如果您通过浏览器中的多个选项卡检查行为,则匹配 URL 的请求可能会排队,而不是同时运行(即您的客户端没有使用“例程”,而不是服务器)。尝试两种不同的浏览器,或者只使用命令行,比如curl并行测试请求。例如(在 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 totalcurl localhost:8080  0.00s user 0.00s system 0% cpu 10.014 totalcurl localhost:8080  0.00s user 0.00s system 0% cpu 10.012 totalcurl localhost:8080  0.00s user 0.00s system 0% cpu 10.019 total你的服务器就像一个魅力。更新我可以在 Chrome 47 上确认这种行为,但也注意到你可以打开多个标签,比如http://localhost:8080/test1,http://localhost:8080/test2等等,你会得到预期的结果。这表明 Chrome 中确实有一些用于匹配 URL 的排队机制。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go