tlo*_*ely 4 concurrency go httpserver
以前标题为:如何根据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)
}
Run Code Online (Sandbox Code Playgroud)
基本上我想要的是监听HTTP连接的主要goroutine,然后将请求的读取和响应传递给在另一个goroutine中生成的处理程序.
有人能指出我正确的方向来实现这个目标吗?最好net/http在go中使用包装.
更新12/21/15 08:46 AM MST
我使用我的网络浏览器(chrome 47)执行了相同的测试,在localhost的根目录下执行了五个请求:8080,结果大致如下:
1st: 10 seconds
2nd: 20 seconds
3rd: 30 seconds
4th: 36 seconds
5th: 38 seconds
Run Code Online (Sandbox Code Playgroud)
所以,希望那些否则会对我的问题进行投票的人会理解我的困惑以及为什么我做了我的假设.我不知道为什么我得到了我在第4和第5次请求时所做的结果.
我使用curl运行相同的测试,结果与@tomasz相同.
我正在使用go1.2.1.
更新12/21/15 02:08 PM MST
根据Per tomasz的建议,我将这个问题从"如何根据每个HTTP请求生成goroutine"改为"为什么这不是用于在Chrome 47中为每个请求生成goroutine的HTTP服务器?"
tom*_*asz 17
一切都很好,您的处理程序在每个请求的单独例程中运行.看一下http.Server.Serve方法的源代码.接受循环的最后一行说:
go c.serve()
Run Code Online (Sandbox Code Playgroud)
问题可能在于您的测试.如果通过浏览器中的多个选项卡检查行为,则匹配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 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
Run Code Online (Sandbox Code Playgroud)
你的服务器就像一个魅力.
更新
我可以在Chrome 47上确认此行为,但也注意到您可以打开多个标签,例如http://localhost:8080/test1,http://localhost:8080/test2等等,您将获得预期的结果.这表明Chrome中确实存在一些用于匹配URL的排队机制.