Анализ производительности WSGI-серверов: вернем uWSGI на место
На прошлой неделе был опубликован перевод статьи двухлетней давности Анализ производительности WSGI-серверов: Часть вторая, где незаслужено был обделен славой uWSGI.
Необходимо срочно перепроверить тесты!
Изначально, я просто хотел воспроизвести тесты, и разобраться, что не так с uWSGI.
В коде отсутствуют версии используемых пакетов и модулей.
Поэтому, запустить тесты и получить аналогичные результаты — не получиться.
Далее мой квест, по запуску тестов и сравнение результатов на графиках.
wrk 4.1.0
Найти спеки, пропатчить, собрать
Информация добавлена в readme.rd.
docker stats
За 2 года изменился вывод статистики.
Была добавлена вторая колонка NAME
, и это сломало парсер статистики.
Что бы через два года не встретить подобную проблему, будем использовать форматированный вывод:
- docker stats > "$BASE/$1.$2.stats" &
+ docker stats --format "} {{.MemUsage}}" > "$BASE/$1.$2.stats" &
И соответственно, немного упростим код парсера.
debian
5, отобразим это в Dokerfile: Сейчас latest образ debian соответствует версии 9.
- FROM debian
+ FROM debian:9.5
4 В апреле 2016 latest соответствовал версии 8.
4. Тем не менеее, Аpache остался почти тем-же: сейчас версия Apache 2. 4. 25, а в 2016 это был Apache 2. 10.
cherrypy tornado uwsgi gunicorn bjoern meinheld mod_wsgi
Даже нет смысла говорить о том, что модули изменились.
Укажем текущие версии:
- RUN pip install cherrypy tornado uwsgi gunicorn bjoern meinheld mod_wsgi
+ RUN pip install cherrypy==17.4.0 \
+ tornado==5.1.1 \
+ uwsgi==2.0.17.1 \
+ gunicorn==19.9.0 \
+ bjoern=2.2.3 \
+ meinheld==0.6.1 \
+ mod_wsgi==4.6.5
Было бы не плохо вынести это в отдельный requirements.txt, но пока оставим так.
cherrypy -> cheroot.wsgi
4. Как было показно выше, актуальная версия 17. 1. 0.
В апреле 2016 вероятно использовалась версия v5. 0 произошли изменения, что отразилось на импорте сервера: 0.
А в 2017 году, в версии 9.
- from cherrypy import wsgiserver
- server = wsgiserver.CherryPyWSGIServer(
+ from cheroot.wsgi import Server as WSGIServer
+ server = WSGIServer(
200, а 7500... После описанных выше правок был запущен первый полноценный тест.
Результаты были хороши: uwsgi выдавал не 3... 5000 запросов в секунду.
Но при детальном рассмотрении полученных графиков, оказалось, что все ответы wrk детектил как ошибки чтения.
1: --http-keepalive и --http11-socket.
Причем, первый дает 7500... После проверки десятка ключей запуска uwsgi, выяснилось, что ошибок нет при включении http1. 5000 запросов в секунду, а второй стабильные 29 тысяч!
0. Наиболее вероятно, что в августе 2016 использовалась версия uWSGI 2. 0. 12 (20151230).
После, в мае, вышла uWSGI 2. 13.
0. Это было знаковое событие, но проблему производительности по версии wrk это не решало вплоть до 2018 года, выходом uWSGI 2. 16:
1 support (--http11-socket) from 2. Back-ported HTTP/1. 1
Вот почему uWSGI рекомендовали использовать с NginX,
А почему это важно в рамках статьи, можно понять из этого тикета 2012 года.
Я пробовал такие версии:
- 2.0.12 для debian 8.4, на девятке она не собирается из-за свежей openssl.
- 2.0.13...2.0.17 для debian 8.4 и 9.5
200 запросов в секунду, мне получить не удалось.
Внимание привлекла строка запуска приложения: Но таких плохих результатов, как 3...
uwsgi --http :9808 --plugin python2 --wsgi-file app.py --processes ...
Указание подключаемого плагина, говорит об установке uwsgi из репозитория, а не pip.
Это может свидетельствовать об отсутствии у автора необходимого опыта работы с данным стеком.
Поэтому, допускаю несколько возможностей:
- тест каждого из uwsgi-серверов производился по отдельности, в разное время.
- имел место какой-то конфликт системной версии uwsgi, и установленой через pip.
- версия wrk автора в 2016, имела какие-то особенности для работы по http1.0
- uwsgi запускался с другим набором параметров
- заказная статья, цифры с потолка.
0. uWSGI на графиках несколько:
Первый uWSGI (v2. 1), выполнялся в долгом тесте, со своими конкурентами, с параметрами:--http11 :9808 --processes 5 --threads 2 --enable-threads
. 17.
0. Потом отдельно был протестирован без тредов:
uWSGIbase (v2. 1), без threads:--http11 :9808 --processes 5
. 17.
0. И, отдельно, версиии uWSGI 2016 года:
uWSGI-v2. 0. 12th-old и uWSGI-v2. 0. 12nt-old — соответственно v2. 4.--http :9808 --http-keepalive --processes 5 --threads 2 --enable-threads
--http :9808 --http-keepalive --processes 5
12 с тредами и без в контейнере debian 8.
uWSGI занимает 2е место, не снижая результатов при увеличении нагрузки.
0.
В low-сегменте uWSGI-v2. 12 лучше всех, даже при увеличении нагрузки.
uWSGI и CherryPy несомненные победители по latency.
Эта картинка аналогична 2016-му году.
Тут видим, как старые uWSGI кушали память с ростом нагрузки.
А новый uWSGI "держит планку", и это о многом говорит.
Cтарые uWSGI начинают резко набирать ошибки уже после 300 открытых соединений.
Bjoern начинает сдавать с 1000 соединений.
Этот момент требует детального рассмотрения. А вот с новым uWSGI странности, начиная 200 соединений, мы получаем 50 ошибок, и число больше не увеличивается.
Все данные собраны тут
uWSGI не так уж плох, или даже очень хорош!
Если вам не нравятся результаты тестов WRK, попробуйте возпользоваться другими инструментами.