大量的请求后,“AB”程序没有响应,为什么?('ab' program freeze

2019-06-17 21:43发布

每当我使用“AB”到基准Web服务器,它会在已经发送大量请求后冻结了一会儿,只有20秒左右后继续。

请看下面的HTTP服务器仿真器,用Ruby写的:

require 'socket'

RESPONSE = "HTTP/1.1 200 OK\r\n" +
           "Connection: close\r\n" +
           "\r\n" +
           "\r\n"

buffer = ""
server = TCPServer.new("127.0.0.1", 3000)  # Create TCP server at port 3000.
server.listen(1024)                        # Set backlog to 1024.
while true
    client = server.accept             # Accept new client.
    client.write(RESPONSE)             # Write a stock "HTTP" response.
    client.close_write                 # Shutdown write part of the socket.
    client.read(nil, buffer)           # Read all data from the socket.  
    client.close                       # Close it.
end

然后我跑AB如下:

ab -n 45000 -c 10 http://127.0.0.1:3000/

在最初的几秒钟,AB,它的工作,因为它是应该,并使用100%的CPU:

Benchmarking 127.0.0.1 (be patient)
Completed 4500 requests
Completed 9000 requests
Completed 13500 requests

约13500请求后,系统的CPU使用率下降到0%。 AB似乎被某物冻结。 这个问题是不是在服务器,因为在这一刻,服务器调用accept()。 约20秒后继续AB,仿佛什么都没有发生,并且将再次使用100%的CPU,只有几秒钟后再次冻结。

我怀疑在内核的东西是节流的连接,但什么,为什么? 我使用的是OS X Leopard的。 我见过类似的行为在Linux上为好,但冻结发生在请求的数量大得多,并且不经常发生。

这个问题让我无法运行大型HTTP基准。

Answer 1:

这听起来像你正在运行的临时端口 。 要进行检查,使用netstat命令来查看在几千口TIME_WAIT状态。

在Mac OS X中的默认临时端口范围为49152至65535,共16384口。 你可以通过检查该sysctl命令:

$ sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535

一旦你用完了临时端口,你通常需要等到TIME_WAIT状态到期(2 *最大段寿命),直到你可以重复使用一个特定的端口号。 您可以通过更改范围在32768开始,这是在Linux和Solaris的默认双端口的数量。 (最大端口号是65535,所以你可以在不增加高端。)

$ sudo sysctl -w net.inet.ip.portrange.first=32768
net.inet.ip.portrange.first: 49152 -> 32768

需要注意的是, 由IANA指定的官方范围为49152至65535,而一些防火墙可以假设动态分配的端口属于这一范围之内。 您可能需要重新配置防火墙,以利用较大范围的本地网络之外。

也可以降低最大片段生命周期( sysctl net.inet.tcp.msl在Mac OS X),其控制的持续时间TIME_WAIT状态,但这是危险的,因为它可能会导致旧的连接弄混了更新那些正在使用相同的端口号。 也有涉及与绑定到特定端口的一些技巧SO_REUSEADDR选项,或者与关闭SO_LINGER选项,但这些也可能导致新老连接混淆,所以通常被认为是不好的想法。



Answer 2:

除了增加端口数量,改变的长度TIME_WAIT在Mac OS X.

这只有在发展的作品,但我现在可以问ab尽可能多的请求,因为我想没有超时。

设置默认的超时时间为1000毫秒,像这样:

$ sudo sysctl -w net.inet.tcp.msl=1000
net.inet.tcp.msl: 15000 -> 1000

在其他的答案中提到的brianp.net页面不再可用。 您可以从检索互联网档案 。



Answer 3:

解决这个问题的另一种选择是,通过添加启用HTTP保持活动"-k"选项。 这将使AB重新使用的TCP连接,并为因此它不会耗尽所有可用端口。 例如:

ab -n 45000 -c 10 -k http://127.0.0.1:3000/



文章来源: 'ab' program freezes after lots of requests, why?