Golang:http服务器离开打开的goroutines
我已经建立了一个用Go编写的http服务器,它每天的访问量略高于1000。我现在有一个问题。在一天的时间里,我似乎从http服务器上获得了一千多个新的Goroutine 我不知道我怎么能搞乱处理者Golang:http服务器离开打开的goroutines,http,go,Http,Go,我已经建立了一个用Go编写的http服务器,它每天的访问量略高于1000。我现在有一个问题。在一天的时间里,我似乎从http服务器上获得了一千多个新的Goroutine 我不知道我怎么能搞乱处理者 http.Handle("/", http.FileServer(http.Dir(config.htdocs_path))) 下面是堆栈中的一个goroutine goroutine 1582 [chan receive]: net.(*pollServer).WaitRead(0xf84007f
http.Handle("/", http.FileServer(http.Dir(config.htdocs_path)))
下面是堆栈中的一个goroutine
goroutine 1582 [chan receive]:
net.(*pollServer).WaitRead(0xf84007f680, 0xf84066dea0, 0xf84007aa80, 0xb, 0x1, ...)
/home/ec2-user/go/src/pkg/net/fd.go:268 +0x73
net.(*netFD).Read(0xf84066dea0, 0xf840ec1000, 0x100000001000, 0x7f7effffffff, 0xf84007c0f0, ...)
/home/ec2-user/go/src/pkg/net/fd.go:428 +0x1ec
net.(*TCPConn).Read(0xf84068aff8, 0xf840ec1000, 0x100000001000, 0xf800000002, 0x0, ...)
/home/ec2-user/go/src/pkg/net/tcpsock_posix.go:87 +0xce
io.(*LimitedReader).Read(0xf840d1bc20, 0xf840ec1000, 0x100000001000, 0xdcb00000000, 0x0, ...)
/home/ec2-user/go/src/pkg/io/io.go:394 +0xc1
bufio.(*Reader).fill(0xf8405b0900, 0xdcb00000000)
/home/ec2-user/go/src/pkg/bufio/bufio.go:77 +0xf0
bufio.(*Reader).ReadSlice(0xf8405b0900, 0xf840d1bc0a, 0x0, 0x0, 0x0, ...)
/home/ec2-user/go/src/pkg/bufio/bufio.go:257 +0x1b6
bufio.(*Reader).ReadLine(0xf8405b0900, 0x0, 0x0, 0x0, 0x0, ...)
/home/ec2-user/go/src/pkg/bufio/bufio.go:283 +0x5b
net/textproto.(*Reader).readLineSlice(0xf840730660, 0xc0, 0x100000000, 0x7f7e00000001)
/home/ec2-user/go/src/pkg/net/textproto/reader.go:55 +0x4f
net/textproto.(*Reader).ReadLine(0xf840730660, 0xf84061f300, 0x0, 0x48411c)
/home/ec2-user/go/src/pkg/net/textproto/reader.go:36 +0x25
net/http.ReadRequest(0xf8405b0900, 0xf84061f300, 0x0, 0x0, 0x100000400ccf60, ...)
/home/ec2-user/go/src/pkg/net/http/request.go:457 +0xb1
net/http.(*conn).readRequest(0xf8402b2b40, 0xf8400e3fc0, 0x0, 0x0, 0xf8405b0a80, ...)
/home/ec2-user/go/src/pkg/net/http/server.go:240 +0xa8
net/http.(*conn).serve(0xf8402b2b40, 0x0)
/home/ec2-user/go/src/pkg/net/http/server.go:594 +0x145
created by net/http.(*Server).Serve
/home/ec2-user/go/src/pkg/net/http/server.go:1040 +0x430
连接似乎卡在读取状态。就像http服务器没有计时一样。默认服务器是否没有读取超时
go版本go1所有这些Goroutine都在阅读的原因是保持活力。当浏览器发送keep-alive标头时,服务器将保持连接打开以接受更多请求。当客户端请求许多小文件,并且TCP连接的开销很大时,这是一件好事。读取超时将确保两次请求之间的连接保持活动的时间不会超过一定的时间。这将关闭keep alive连接,但也会阻止某人在超过超时的时间内上载。不幸的是,目前还没有特定于保持活动的超时选项 默认情况下,没有超时。您可以在服务器结构中设置超时
在HTTP连接上使用ReadTimeout和WriteTimeout时要小心。我认为他们不会做你期望他们做的事。特别是,它们倾向于使连接处于不可用状态,而不实际关闭它们。请参阅以了解详细信息,特别是,我看到当HTTP处理程序时间超过超时时,ReadTimeout使连接不可用并导致响应被丢弃在地板上的情况。如果您将超时设置为超过任何处理程序的响应时间的大值,您可能就可以了。Stephen的回答对我来说只适用于以下情况:服务器可以告诉其客户端它不希望或不支持保持连接打开。要执行此操作,请在服务前设置相应的标志:
server := &http.Server{
// ... see Stephen's answer
}
server.SetKeepAlivesEnabled(false)
server.ListenAndServe()
这将设置响应头
Connection:close
,大多数客户端将从其一侧终止连接 对不起,我不知道如何将它标记为正确。必须弄清楚。ReadTimeout和TimeoutHandler之间的区别是什么?他们做同样的事,不是吗?请注意,对于go>=1.8,有ReadTimeout
、ReadHeaderTimeout
、WriteTimeout
和IdleTimeout
以获得更精细的粒度。另请参阅。
server := &http.Server{
// ... see Stephen's answer
}
server.SetKeepAlivesEnabled(false)
server.ListenAndServe()