每当我使用 '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,只是在几秒钟后再次冻结。
我怀疑内核中的某些东西正在限制连接,但是什么以及为什么?我正在使用 OS X Leopard。我在 Linux 上也看到过类似的行为,尽管冻结发生在更多请求的情况下,并且不会经常发生。
这个问题使我无法运行大型 HTTP 基准测试。