源码位于go标准库的net/http/server.go
中。
1:从入口点http.ListenAndServe
跟代码
func (srv *Server) ListenAndServe() error {
addr := srv.Addr //获取地址
...
ln, err := net.Listen("tcp", addr) //创建tcp连接
...
return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) //阻塞监听请求
}
2:继续往下跟srv.Serve()
,此函数用于阻塞监听HTTP请求。
func (srv *Server) Serve(l net.Listener) error {
...
for { //死循环
rw, e := l.Accept() //抓请求
...
go c.serve(ctx) //开协程处理请求
//!!!注意:这里每一个请求都开了一个协程
}
3:跟一下c.serve(ctx)
函数
func (c *conn) serve(ctx context.Context) {
...
serverHandler{c.server}.ServeHTTP(w, w.req)
//创建了多路复用器,并且调用了ServeHTTP
...
}
总结:只是简单看一眼,主要看的是http标准库自己有没有开协程。答案很明显,对于每一个请求,http标准库都会开启一个协程去处理。通过设置rw的超时时间可以控制协程的数量(并不精准,容易引发雪崩)。而多路复用器的作用主要是通过url提供的API名找到对应的函数。