为什么golang中的web服务器不处理并发请求?

Ste*_*nov 58 go

这个简单的HTTP服务器包含对time.Sleep()的调用,使每个请求花费五秒钟.当我尝试在浏览器中快速加载多个选项卡时,很明显每个请求都按顺序排队和处理.如何让它处理并发请求?

package main

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

func serve(w http.ResponseWriter, r *http.Request) {
   fmt.Fprintln(w, "Hello, world.")
   time.Sleep(5 * time.Second)
}

func main() {
   http.HandleFunc("/", serve)
   http.ListenAndServe(":1234", nil) 
}
Run Code Online (Sandbox Code Playgroud)

实际上,我在写完这个问题之后就找到了答案,而且非常微妙.无论如何,我发布它,因为我在Google上找不到答案.你能看出我做错了什么吗?

tux*_*21b 101

您的程序已经同时处理请求.您可以ab使用Apache 2附带的基准测试工具进行测试:

ab -c 500 -n 500 http://localhost:1234/
Run Code Online (Sandbox Code Playgroud)

在我的系统上,基准测试总共需要5043ms来处理所有500个并发请求.它只是您的浏览器限制每个网站的连接数.

基准测试Go程序并不是那么容易,因为您需要确保您的基准测试工具不是瓶颈,并且它还能够处理那么多并发连接.因此,使用几台专用计算机来生成负载是个好主意.

  • 我想编辑你的答案,从最后一段删除"Go"一词...... ;-) (29认同)
  • goroutines产生得更早.http.ListenAndServe在无限循环中接受新连接,并生成新的goroutine来处理它们. (11认同)
  • 很高兴知道.我希望包文档和我在网上看到的很多例子让这一点更加清晰:-) (8认同)
  • 我试图理解代码:我们是否暗示http.HandleFunc()产生一个goroutine来处理请求,所以它立即返回? (2认同)

fac*_*tum 10

从Server.go开始,当接受连接时,在Serve函数中生成go例程.以下是片段: -

// Serve accepts incoming connections on the Listener l, creating a 
// new service goroutine for each.  The service goroutines read requests and
// then call srv.Handler to reply to them.
func (srv *Server) Serve(l net.Listener) error {
        for {
            rw, e := l.Accept()
               if e != nil {
......
            c, err := srv.newConn(rw)
            if err != nil {
                continue
            }
            c.setState(c.rwc, StateNew) // before Serve can return
            go c.serve()
        }
}
Run Code Online (Sandbox Code Playgroud)