результаты тестирования производительности шести ведущих веб-фреймворков

Несколько месяцев назад я выбирал фреймворк для работы. Главную роль для меня играли простота его использования, стабильность и производительность.

За неимением в Интернете конкретной развернутой информации о сравнении скорости фреймворков, (я нашел только одно достаточно голое тестирование: оно ограничивалось тремя фреймворками RubyOnRails, Django, Symfony и не содержало деталей), я провел детальный анализ для определения самого оптимального из шести ведущих по наиболее значимым параметрам.

Итак, цель тестирования - определение скорости работы самих фреймворков и сравнения их друг с другом по скорости генерирования страниц и максимальному количеству запросов на данной конфигурации.
Я выбрал тестовую модель, при которой контроллер рендерил определенный шаблон и генерировал ответ. В итоге получался HTML-файл c "Hello World!". База данных в тесте не используется, так как она сама накладывает сильные ограничения на скорость.

Я не пытался сравнить функциональность фреймворков, коммьюнити, работу с базой данных. Мне важно было определить скорость работы именно движка MVC фреймворка, по возможности уменьшив влияние внешних факторов.

Поэтому я использовал связку Nginx + FCGI.

Были протестированы следующие фреймворки:

- CodeIgniter на PHP;
- Catalyst на Perl;
- Django на Python;
- Django на Python с Psyco;
- RubyOnRails на Ruby;
- Symfony на PHP;
- TurboGears на Python.

Тестирование проводил на следующем железе и софте:

- CPU: AMD OpteronT Processor 146 (2 GHz);
- Memory: 2 GB;
- OS: Debian 3.1 (Linux 2.6.14);
- Web-Server: nginx/0.5.5.

Версии фреймворков:

- CodeIgniter 1.5.1;
- Catalyst 5.7006 Rev.5996;
- Django Rev.4254 (28Dec.2006);
- RoR 1.1.6;
- RoR 1.2.1;
- Symfony 1.0beta2 SVN-Rev 3122;
- Turbogears 1.0b3 Rev.2323.

Версии языков программировнаия:

- Python 2.4.4;
- Python Psyco 1.5.2;
- Flup Rev.2303;
- Ruby 1.8.5-p12;
- mongrel 0.3.13.4;
- PHP 5.2.0 (cgi-fcgi);
- Perl v5.8.4, CPAN ver 1.8802.

Программы для тестирования:

- Siege 2.65;
- Http_load 12.03.2006;
- ab 2.0.41-dev Rev: 1.141.

методика тестирования

1. Измерение памяти (ps aux: VSZ "virtual set size" и RSS "resident set size").

2. Тестирование ApacheBenchmark (2 раза подряд):

ab -c 5 -n 1000 http://project.com/

3. Измерение памяти и израсходованного процессорного времени (ps aux: VSZ, RSS, %CPU, %MEM).

4. Перезапуск фреймворка.

5. Тестирование ApacheBenchmark (2 раза подряд):

ab -c 100 -n 10000 http://project.com/

6. Измерение памяти и израсходованного процессорного времени.

7. Перезапуск фреймворка.

8. Измерение http_load:

http_load -rate 10 -seconds 5 project.com

9. Измерение памяти и израсходованного процессорного времени.

10. Перезапуск фреймворка.

11. Тест Siege c 50 одновременными пользователями в течение одной минуты:

siege -d1 -t1M -c50 project.com

12. Тест Siege c 200 одновременными пользователями в течение одной минуты:

siege -d1 -t1M -c200 project.com

13. Тест Siege c 300 одновременными пользователями в течение одной минуты:

siege -d1 -t1M -c300 project.com

14. Измерение памяти и израсходованного процессорного времени.

комментарии к методике

Для начала я прогнал один Nginx с простейшим конфигом, при котором на любой запрос выдается точечный прозрачный gif-файл размером 43 байта, генерируемый самим сервером.

Этим тестом была определена примерная максимальная пропускная способность самого сервера. Забегая вперед скажу, что запас его мощности в 10 раз больше пропускной способности самого быстрого фреймворка.

Все фреймворки запускались как FastCGI 127.0.0.1:PORT. Если фреймворком предусматриваются development- и production-режимы, то я работал с production.

В nginx использован одинаковый для всех конфиг.

Перезапуск фреймворка я проводил, чтобы очистить статистику между тестами разными программами.

Мои субъективные впечатления по каждому фреймворку при инсталляции и запуске.

CodeIgniter - легко ставится и быстро настраивается. Никаких проблем с ним не возникло. Для запуска использовал spawn-php.sh с пятью процессами. Довольно шустрый для PHP фреймворк.

Catalyst. Для начала надо установить CPAN и парочку модулей для FCGI. Установка выглядела несколько запутанно. Запуск также не простой. Для начала нужно запустить фреймворк:

./CatInABox/start.sh

Потом проект:

./script/world_fastcgi.pl -l 127.0.0.1:9500 -n 5

Код не так прост, но разобраться можно.

Django. Легко ставится из репозитария. Также легко создаются пректы. Запускал двумя методами prefork и threaded. Хотя питон не очень хорошо работает с тредами.

python manage.py runfcgi method=threaded host=127.0.0.1 port=8801
python manage.py runfcgi method=prefork host=127.0.0.1 port=8801


Также проверил фреймворк с модулем ускорения psyco. В manage.py вставил:

from django.core.management import execute_manager
import psyco
psyco.full()


RubyOnRails. Его было легко поставить, следуя инструкции с сайта, но оказалось сложно запустить. Хотя в интернете видел разные конфигурации для связки Nginx + FastCGI, мне не удалось запустить его вместе с nginx.

С lighttpd + FCGI же все запустилось нормально. Поэтому я воспользовался "официальной" рекомендацией запускать через сервер mongrel. Nginx+FastCGI быстрее примерно в 1.29 раз чем Nginx+Mongrel.
Запускал 5 серверов mongrel:

mongrel_rails start -d --port 8501
mongrel_rails start -d --port 8502
mongrel_rails start -d --port 8503
mongrel_rails start -d --port 8504
mongrel_rails start -d --port 8505


Через пару дней после проведения тестов вышла новая версия RoR 1.2.1
Я, конечно, проверил и ее со всеми параметрами, обновил только фреймворк. Результаты несколько шокировали: падение производительности в 2 раза на всех тестах.

Symfony. Поставить было не сложно, но зато потом намучался с самим проектом. Довольно запутанно. Для запуска использовал также spawn-php.sh с пятью процессами.

TurboGears. При установке возникли небольшие проблемы, которые, немного повозившись, все же решил. Для запуска в threaded режиме использовал рекомендованный скрипт, в котором кое что изменил.

результаты



Рис. 1. Тест ApacheBenchmark. Таблица со скоростью обработки запросов.

Примечания к рисунку 1:

*1) во второй раз фреймворк завис и не отвечал;

*2) для перевода скорости работы из mongrel в fastcgi использовался коэффициент умножения по Ковырину =1.29.



Рис. 2. Тест ApacheBenchmark. Диаграмма со скоростью обработки запросов. Тест „ab c 5 n 1000“.



Рис. 3. Тест ApacheBenchmark. Диаграмма со скоростью обработки запросов. Тест „ab c 100 n 10000“.





Примечание к рисунку 4:

*3) Питон устроен так, что при сильной нагрузке в режиме prefork он перестартует свои процессы. Поэтому невозможно определить реальную загрузку процесора и максимальное потребление памяти.



Рис. 5. Тест ApacheBenchmark. VSZ "virtual set size".



Рис. 6. Тест ApacheBenchmark. RSS "resident set size".



Рис. 7. Тест ApacheBenchmark. Загрузка процессора.



Рис. 8. Тест http_load. Таблица с результатами.



<Рис. 9. Siege тест. Общая таблица с результатами.

выводы

В общем-то результаты видны по таблицам и графикам. Позволю себе лишь некоторые дополнения.

Меньше всего потребление процессора у django. Удивил Catalyst, который при чрезмерной нагрузке резко начинает грузить процессор. Хотя потерь запросов не наблюдалось. RoR 1.2.1 под большой нагрузкой также сильно грузит процессор.

Интересно было у TurboGears, который показал низкое потребление времени CPU в тесте "ab", но зато в siege-тесте имел самый худший результат. Потребление памяти самым большим оказалось у Catalyst, у RoR оно скорее обусловлено запуском через mongrel.

PHP-фреймворки даже в спокойном состоянии занимают много ресурсов CPU.

Среднее время коннекта для всех примерна равно. Время первого отклика сильно рознится. Тут отличился Django, имея наименьшее среднее время и самое высокое максимальное время коннекта. Фреймворки на питоне показали себя с хорошей стороны, а вот Ruby разочаровал.

Во время siege-теста наблюдались потери при большом количестве "concurrent users" у CodeIgniter, Symfony, RoR 1.2.1 & 1.1.6.
Ruby быстр при небольшой нагрузке, но резко теряет производительность при большом количестве пользователей.

Psyco-модуль ускоряет Django на 15-30%, но за это приходится расплачиваться возросшим потреблением памяти VSZ на 80% в prefork-режиме и на 400% (!!!) в threaded-режиме. RSS-потребление увеличивается в 2-2.5 раза.

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

В threaded-режиме Django зависал под большой нагрузкой и не отвечал на запросы. Это же происходило и с TurboGears. Связано это с плохой работой питона в threaded-режиме.

распределение мест

Минимум с трехкратным превосходством над ближайшими конкурентами победил Django.

Второе и третье места поделили TurboGears и RoR 1.1.6, так как они одинаково быстры, но ведут себя по-разному при разных нагрузках, обгоняя друг друга.

Catalyst. Честно говоря, от фреймворка на перле я ожидал большего.

CodeIgniter. Фреймворки на PHP, как и ожидалось, оказались самыми медленными. Но CodeIgniter можно посоветовать тем, кто хочет программировать только на PHP и в тоже время иметь удобную и относительно быструю систему.

Результаты RoR 1.2.1 сильно шокировали: падение производительности в 2-4 раза по сравнению с 1.1.6 версией. Время первого отклика в http_load также больше в 2 раза, чрезмерно высокое потребление процессорного времени при высокой нагрузке, все это скорее говорит о какой-то ошибке в новой версии.

Symfony досталось последнее место. Очень сложный и медленный фреймворк. Разница с Django - до 35 (!!!) раз.



Alrond


Сетевые решения. Статья была опубликована в номере 02 за 2007 год в рубрике лабораторная работа

©1999-2024 Сетевые решения