воскресенье, 22 января 2012 г.

Noir benchmark

Решил немного потестить простое веб-приложение, описанное в предыдущей статье. Тесты проводились на ноутбуке Acer Aspire 5745G (Intel Core i5 2.26Ghz, 4Gb). Обнаружил следующее.

Во-первых, при запуске сайта командой lein run запускаются два java-процесса. Первый, занимающий 28.8Mb -- видимо служебный, т.к. никакие его характерстики за время работы приложения не менялись. Второй, сходу запросивший 76.7Mb, -- само веб-приложение. Я создал два типа сущностей: mypage и mypage2 с CRUD-действиями для них, не используя БД. Т.е. скорость обработки запроса целиком зависила от скорости работы java-машины и не зависела от скорости ввода-вывода или поиска данных в таблицах. При обращении к различным действиям сущности mypage объем потребляемой памяти возрос до 90.3Mb. При обращении к mypage2 -- до 93.5Mb. При повторном обращении к этим же сущностям потребление памяти никак не поменялось. При перезапуске приложения цифры изменились до 96Mb и 99Mb.

Интересно взглянуть на производительность веб-приложения под нагрузкой. Я создал скрипт, делающий 70000 таких запросов:
wget http://localhost:8080/mypage
wget http://localhost:8080/mypage/848867
wget http://localhost:8080/mypage/edit/996283
wget http://localhost:8080/mypage/527997
wget http://localhost:8080/mypage/edit/410389

Сущности с указанными айдишниками, естественно, существовали в приложении. Эти 70тыс. запросов jetty обработал за полчаса, отдавая, таким образом, примерно 2333 динамических страницы в минуту или примерно 39 в секунду.

Самым интересным для меня в этом эксперименте стало потребление памяти и процессорного времени.

Сначала jetty затребовал 92% процессорного времени, но его запросы довольно быстро сократились до 40%. Затем, довольно медленно, и они стали снижаться. К концу эксперимента jetty потреблял всего 4% процессорного времени.

Аналогично, запросы памяти сначала были немалыми. Довольно быстро jetty "откушал" 232.8Mb, после чего потребляемая память стала уверенно снижаться, остановившись на отметке 84.6Mb.

Надо еще учитывать, что нагрузка на сервер была ограничена возможностями консоли, в которой работал wget, ведь его вывод на экран тоже занимает какое-то время. Но, по крайней мере, верхнюю границу запросов процессора и памяти мы получили. Нижняя, естественно, достоверной не является.

Такое снижение потребляемой памяти и процессора стало возможно благодаря run-time оптимизациям java-машины (в Sun некогда здорово над этим поработали). Вот и скажи теперь, что java -- медленная...

8 комментариев:

  1. Не знаю, что именно там было в страницах, но по 39 страниц в секунду это раз в 10 меньше, чем ожидалось на подобном тесте. Вам не кажется?

    ОтветитьУдалить
  2. Еще как кажется. Но, думаю, дело тут не в веб-приложении, а в методе тестирования. У меня под рукой был wget, им и тестил. Последовательно. С выводом всякой фигни на экран. Если распараллелить запросы и убрать вывод в консоль, то wget сможет сделать больше запросов в секунду, и мы увидели бы работу jetty на пределе. Кстати, а чем лучше затестить веб-приложение под нагрузкой?

    ОтветитьУдалить
  3. Для нагрузочного тестирования проще всего использовать curl-loader, пример конфигурации http://twiturl.ru/2trd. Интересно будет узнать работу приложения под curl-loader'ом - с распараллеливонием запросов.

    ОтветитьУдалить
  4. А насколько я понимаю тут скорострельность зависит от того насколько точным будут попадания jit? То есть это достаточно реальное приложение, чтобы говорить о том, что jit будет выдавать стабильно хороший результат?

    ОтветитьУдалить
  5. httperf works fine as benchmarking tool http://www.hpl.hp.com/research/linux/httperf/

    ОтветитьУдалить
  6. Оки, в ближайшее время попробую httperf и curl-loader.

    ОтветитьУдалить
  7. Попробуйте ab для тестирования. Конфигов не надо, только параметры командной строки.
    http://httpd.apache.org/docs/2.0/programs/ab.html

    ОтветитьУдалить
  8. Я потестил утилитой ab и получил, как и ожидалось, значительно лучшие результаты.

    Concurrency Level: 100
    Time taken for tests: 45.410 seconds
    Complete requests: 100000
    Requests per second: 2202.17 [#/sec] (mean)

    При 100 параллельных запросах в секунду обрабатывалось 2202 запроса, что 56,5 раз больше, чем при тестах wget-ом. Без распараллеливания в секунду обрабатывается примерно 579 запросов. На пике jetty потреблял 313Мб памяти и 308% процессорного времени (у меня 4 ядра).

    ОтветитьУдалить