【发布时间】:2015-05-20 14:32:05
【问题描述】:
package main
import (
"io"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world!\n")
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":8000", nil)
}
我有几个非常基本的 HTTP 服务器,它们都存在这个问题。
$ ab -c 1000 -n 10000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
apr_socket_recv: Connection refused (61)
Total of 5112 requests completed
使用较小的并发值,事情仍然会失败。对我来说,这个问题似乎通常出现在 5k-6k 左右:
$ ab -c 10 -n 10000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
apr_socket_recv: Operation timed out (60)
Total of 6277 requests completed
事实上,您可以完全放弃并发,但问题仍然(有时)会发生:
$ ab -c 1 -n 10000 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
apr_socket_recv: Operation timed out (60)
Total of 6278 requests completed
我不禁想知道我是否在某个地方遇到了某种操作系统限制?我该怎么说?我将如何缓解?
【问题讨论】:
-
ab不是很好,Go http 服务器远远胜过它。ab在 osx 上也很糟糕。您正在耗尽一些本地资源,例如可用的套接字。 -
我认为默认情况下,Go服务器的连接没有关闭,因此可以重用,但似乎
ab没有重用或关闭它们的速度不够快,所以最大打开连接是到达。您可以尝试在您的处理程序中将r.Close设置为true(我还没有实际测试过)。 -
在我的笔记本电脑上使用
wrk,你的hello服务器达到46000req/sec(@Ainar-G:那也只使用了GOMAXPROCS=1。当你被网络绑定时,低GOMAXPROCS通常更多高效)。 -
@siritinga:这不会有帮助,因为
ab只使用 http/1.0 并且没有通过 keepalive 调用。连接必须每次都关闭。 -
@BobAman:尝试了
httperf,在我的系统上它似乎比ab -k还要慢,但处理100k 请求仍然没有问题。这个基准确实没有用,因为基准测试工具(和本地网络堆栈)的测试甚至比 Go 服务器更多。
标签: http go osx-yosemite