Sockets ';ab和x27;程序在大量请求后冻结,为什么?

Sockets ';ab和x27;程序在大量请求后冻结,为什么?,sockets,debugging,networking,throttling,apachebench,Sockets,Debugging,Networking,Throttling,Apachebench,每当我使用“ab”对web服务器进行基准测试时,它在发送了大量请求后会冻结一段时间,直到20秒左右才继续 考虑以下用Ruby编写的HTTP服务器模拟器: 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.

每当我使用“ab”对web服务器进行基准测试时,它在发送了大量请求后会冻结一段时间,直到20秒左右才继续

考虑以下用Ruby编写的HTTP服务器模拟器:

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,但几秒钟后再次冻结

我怀疑内核中有什么东西在限制连接,但这是什么,为什么?我正在使用OSX Leopard。我在Linux上也看到过类似的行为,尽管冻结发生在大量的请求上,而且并不经常发生


这个问题使我无法运行大型HTTP基准测试。

听起来您的HTTP基准测试快用完了。要进行检查,请使用命令并查找状态中的数千个端口

在Mac OS X上,默认临时端口范围为49152到65535,总共有16384个端口。您可以使用以下命令进行检查:

请注意,端口号为49152到65535,一些防火墙可能会假定动态分配的端口在该范围内。您可能需要重新配置防火墙,以便使用本地网络之外的更大范围


还可以减少最大段生存期(Mac OS X上的sysctl net.inet.tcp.msl),它控制
等待时间
状态的持续时间,但这是危险的,因为它可能会导致旧连接与使用相同端口号的新连接混淆。还有一些技巧涉及使用
SO\u REUSEADDR
选项绑定到特定端口,或使用
SO\u LINGER
选项关闭,但这些技巧也可能导致新旧连接混淆,因此通常被认为是坏主意。

不是增加端口数量,在Mac OS X上更改等待时间的长度

这只在开发中起作用,但我现在可以请求
ab
,以获得我想要的任意多的请求,而无需超时

将默认超时设置为1000ms,如下所示:

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

另一个答案中提到的brianp.net页面不再可用。您可以从中检索它。

解决此问题的另一个选项是通过添加
“-k”
选项来启用HTTP KeepAlive。这将使ab重新使用TCP连接,因此不会耗尽所有可用端口。例如:


ab-n45000-c10-khttp://127.0.0.1:3000/

是的,就是这样。我按照上的说明更改了MSL,现在一切正常。谢谢非常感谢,这解决了我遇到的同一个问题。在这里,我认为这是一个
Golang
问题。。每16000个来自
ab
$ sudo sysctl -w net.inet.ip.portrange.first=32768 net.inet.ip.portrange.first: 49152 -> 32768
$ sudo sysctl -w net.inet.tcp.msl=1000
net.inet.tcp.msl: 15000 -> 1000