Почему простой Тонкий сервер перестает отвечать на 16500 запросов при тестировании?
Возможный дубликат:
'ab' программа зависает после большого количества запросов, почему?
Вот простой тестовый сервер:
require 'rubygems'
require 'rack'
require 'thin'
class HelloWorld
def call(env)
[200, {"Content-Type" => "text/plain"}, "OK"]
end
end
Rack::Handler::Thin.run HelloWorld.new, :Port => 9294
#I've tried with these added too, 'rack.multithread' => true, 'rack.multiprocess' => true
Вот тестовый прогон:
$ ab -n 20000 http://0.0.0.0:9294/sdf
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 0.0.0.0 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
apr_poll: The timeout specified has expired (70007)
Total of 16347 requests completed
Это ломается около 16500. Почему? Как я могу узнать, что происходит. Это GC в ruby или что-то с количеством доступных сетевых сокетов на компьютере с OS X. У меня есть память MPG 2,5 ГГц 6G.
редактировать
После некоторого обсуждения здесь и тестирования различных вещей, кажется, что изменение net.inet.tcp.msl с 15000 до 1000 мс делает проблему тестирования высокочастотных веб-серверов с помощью ab.
sudo sysctl -w net.inet.tcp.msl=1000 # this is only good for local development
Смотрите ссылочный вопрос с ответом на эту проблему. 'ab' программа зависает после большого количества запросов, почему?
2 ответа
Я добавлю решение здесь для ясности. Правильное решение для управления выполнением высокочастотных тестов с помощью ab on os X - изменить настройку "net.inet.tcp.msl" с 15000 мс до 1000 мс. Это должно быть сделано только на блоках разработки.
sudo sysctl -w net.inet.tcp.msl=1000 # this is only good for local development
Этот ответ был найден после хорошей детективной работы, выполненной в комментариях здесь, и приходит от ответа на очень похожий вопрос, вот ответ: /questions/45952513/ab-programma-zavisaet-posle-bolshogo-kolichestva-zaprosov-pochemu/45952554#45952554
Я думаю, что у меня это есть.
Когда ab устанавливает соединение с вашим тестовым сервером, он открывает исходный порт (скажем, 50134) и устанавливает соединение с портом назначения (9294).
Порты, которые ab открывает для порта источника, определяются настройками sysctl net.inet.ip.portrange.first и net.inet.ip.portrange.last. Например, на моей машине:
philippotter ~ $ sysctl -a | grep ip.portrange
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.hilast: 65535
Это означает, что исходные порты ab будут в диапазоне от 49152 до 65535, что в сумме составляет 16384.
HTTP - это протокол TCP. Когда соединение TCP закрыто, оно переходит в состояние TIME_WAIT, ожидая, пока оставшиеся транзитные пакеты достигнут места назначения. Это означает, что порт не может использоваться для каких-либо других целей, пока не истечет время ожидания.
Итак, собрав все это вместе, ab очень быстро использует все доступные исходные порты; они переходят в состояние TIME_WAIT; они не могут быть повторно использованы; ab не может создать больше соединений.
Вы можете увидеть это, если убьете ab, когда он зависнет, и запустите его снова - он не сможет создавать никаких соединений!