2012-02-06 1 views
5

Можно создать дубликат:
'ab' program freezes after lots of requests, why?Почему простой тонкий сервер перестает отвечать на 16500 запросов при бенчмаркинге?

Вот простой тестовый сервер:

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 в рубине или это что-то с количеством доступных сетевых сокетов на компьютере OS X. У меня есть память MPB 2.5 Ghz 6G.


Редактировать

После некоторого обсуждения здесь и тестирования различных вещей, похоже, меняется net.inet.tcp.msl от 15000 до 1000 мс делает задачу проверки высокочастотных веб-серверов с аб уходят.

sudo sysctl -w net.inet.tcp.msl=1000 # this is only good for local development 

См. Связанный вопрос с ответом на эту проблему. 'ab' program freezes after lots of requests, why?

+1

ли вы найти причину ?? Потенциальное объяснение может заключаться в том, что ОС держит сокет в «недавно использованном» состоянии и не использует его повторно в течение нескольких минут. По-видимому, можно переконфигурировать IP-уровень ОС, чтобы этого не сделать. – radiospiel

+1

Если это помогает, я могу воспроизвести это точное поведение на моем MBP. Завершено 16359 запросов. Не знаю, что вызывает его. –

+1

Хм, думая вслух, это число подозрительно близко к 16384 ... –

ответ

5

Я добавлю решение здесь ради ясности. Правильное решение для проведения высокочастотных тестов с ab на os X - это изменить настройку 'net.inet.tcp.msl' с 15000мс до 1000 мс. Это нужно делать только на ящиках разработки.

sudo sysctl -w net.inet.tcp.msl=1000 # this is only good for local development 

Этот ответ был найден после того, как хороший детектив работы, выполненные в комментариях здесь и происходит от ответа на очень похожий вопрос вот ответ: https://stackoverflow.com/a/6699135/155031

2

Думаю, у меня это есть.

Когда 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 state, в то время как оно ожидает, что все оставшиеся транзитные пакеты достигнут своих адресатов. Это означает, что порт не может использоваться для каких-либо других целей, пока не будет достигнут тайм-аут.

Таким образом, все это вместе, ab использует все доступные порты источника очень быстро; они входят в состояние TIME_WAIT; они не могут быть повторно использованы; ab не может создавать никаких дополнительных соединений.

Вы можете увидеть это, если вы убьете ab, когда он зависает, и запустите его снова - он не сможет создать любых подключений!

+1

Похоже, мы ближе к вопросу! Но почему нет вывода 'netstat -p tcp', заполненного TIME_WAITS, и почему другие программы могут открывать соединения? – sunkencity

+0

Запустив новый сервер и запустив ab, кажется, что последний запрос зависает на 'tcp4 0 0 localhost.52892 localhost.http SYN_SENT', а затем через некоторое время время ожидания запроса. (Я попытался запустить сервер на порту 80 вместо более высокого порта) – sunkencity

+0

@sunkencity hmm, хорошие вопросы. Возможно, это не TIME_WAIT. –