Почему простой Тонкий сервер перестает отвечать на 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, когда он зависнет, и запустите его снова - он не сможет создавать никаких соединений!

Другие вопросы по тегам