LINUX.ORG.RU
решено ФорумAdmin

uwsgi + nginx + 20 rps = смерть

 , ,


0

2

Проблема такая: был веб сервер (www0), он перестал справляться с нагрузкой. Решил поставить ещё один вебсервер (www1), но он помирает на шутейной нагрузке в 20 запросов в секунду, хочу понять почему.

Детали:
- проект на django, запросы к БД лёгкие и на каждую страничку их мало (до 5 селектов, редко один insert или update), статистика БД тормозов не показывает, странички возвращают до 6 килобайт, никаких долгих вычислений в скриптах нет;
- на www0 крутятся apache, nginx, mysql, memcached;
- на www1 nginx, uwsgi, memcached;
- www1 помирает через минуту после направления трафика, uwsgi либо не успевает обработать все запросы либо у меня что-то напутано с конфигурацией и запросы вовремя не уходят клиенту, в итоге клиент отваливается по таймауту. Это я к тому, что в логах ошибок uwsgi только одна проблема - broken pipe, никакой нехватки файлов или недоступности сокета нет.

Пробовал ставить gunicorn вместо uwsgi, переносить БД локально на www0, результата нет. nginx в топе есть, но берёт не более 1%, всё остальное кушает uwsgi, по памяти затыков нет.

Машина www1 - двухъядерный Athlon 64 5600+ X2, 2GB памяти (в хетцнере, ага). Конфиги:
uwsgi.conf
nginx.conf
domain.com (nginx)
uwsgi_params
sysctl -a

Вот так выглядит график загрузки проца и потребления памяти.

Это у меня что-то не так настроено или просто машина слабая?

★★

Ответ на: комментарий от baverman

DEBUG=True

не влияет

Что с io?

Включил на пару минут, вот как выглядел график до момента выключения (спад - это не момент выключения, я подозреваю, что спад это когда каждый запрос стал отваливаться).

Данные iotop после спада на графике: iotop

SOmni ★★ ()
Ответ на: комментарий от SOmni

не, дебаг отключен,

На логирование исключений это не влияет.

baverman ★★★ ()
processes = 4
enable-threads
threads = 4

это у тебя типа и треды и форки? а не пробовал что-то одно сделать? у меня например вот так:

processes = 1
threads = 8
master = True
enable-threads = True
disable-write-exception = True
disable-logging = True
vacuum = True

Komintern ★★★★★ ()
Ответ на: комментарий от Komintern

а не пробовал что-то одно сделать

пробовал разное, на ситуацию не влияло.

У тебя динамика? Какая машина и сколько запросов тянет?

SOmni ★★ ()
Последнее исправление: SOmni (всего исправлений: 1)

Профайлером не пробовал статистику собирать?

У меня с гуникорном спокойно тысяча запросов параллельных отрабатывается (практически на всех сайтах, кроме явно тяжелых страниц), что-то тут явно не так у тебя.

provaton ★★★★★ ()
Последнее исправление: provaton (всего исправлений: 1)
Ответ на: комментарий от SOmni

динамика - в смысле? ну джанга работает, 2 небольших интернет-магазина. нагрузка далеко не 20 запросов в секунду, но меня просто смутило что и треды и форки. обычно юзается либо то либо другое. еще у uwsgi были какие-то грабли с системными семафорами, можешь в эту сторону погуглить.

Komintern ★★★★★ ()
Последнее исправление: Komintern (всего исправлений: 1)
Ответ на: комментарий от Komintern

у uwsgi были какие-то грабли с системными семафорами

даже если так, это не объясняет, почему gunicorn ведёт себя точно так же.

SOmni ★★ ()
Ответ на: комментарий от provaton

Попробую. Сейчас пока ради эксперимента взял точно такую же машину как www0 (www2, 8 ядер), но вместо связки apache+nginx поставил опять uwsgi+nginx. Что-то новая машина подозрительно похоже подтормаживает в то время как www0 на вчетверо более высокой нагрузке работает гораздо лучше. И затыка по процессору уже нет. Можешь показать настройки гуникорна и вебсервера? Ну и sysctl -a, если не жалко. Какая машина у тебя?

SOmni ★★ ()
Последнее исправление: SOmni (всего исправлений: 1)
Ответ на: комментарий от provaton

По поводу профайлера. Newrelic, в общем-то, замеряет время работы отдельных функций. Для самого частого запроса оно такое:
www0 - 390ms;
www1 - 565ms;
www2 - 663ms.
Т.е. полсекунды на запрос.

SOmni ★★ ()
Ответ на: комментарий от SOmni

Машина - Intel(R) Xeon(R) CPU E5520 @ 2.27GHz, 8 ядер, 4ГБ РАМ.

Гуникорн запускаю так:

manage.py run_gunicorn -k gevent --preload -w 4 -b 127.0.0.1:8010

(Правда 4 воркера это мало, но так как посещаемость пока низкая, то больше смысла нет ставить).

В нгинксе обычная прокси:

        location / {
		proxy_pass http://localhost:8010;
        	include proxy_params;
	}

sysctl стандартный дебиановский, вообще там ничего не менял.

В принципе, полсекунды на реквест - это не так уж много. Если посещаемость большая, то кеширующий прокси должен решить.

provaton ★★★★★ ()
Ответ на: комментарий от provaton

Кэшировать проксёй нельзя, специфика приложения.
Komintern, кажется, был прав и всё дело в тредах. Ну или я просто не умею их готовить. Рассказываю:
1. треды включены, 2 процесса по 6 тредов - тормоза: uwsgi работает полсекунды, nginx ждёт полминуты (не хватает обработчиков uwsgi, значит);
2. треды включены, 1 процесс, 12 тредов - тормоза: uwsgi работает по 5 секунд, nginx отваливается по таймауту (вероятно, что-то не так с тредами в uwsgi);
3. треды выключены, 12 процессов - всё хорошо. Правда la в районе 10 болтается, но, что удивительно, это несильно сказывается на скорости ответа. На 8-ядерном сервере при таком раскладе вообще всё летает. Буду дальше пробовать крутить процессы. Всем спасибо.

SOmni ★★ ()
Ответ на: комментарий от SOmni

Кэшировать проксёй нельзя, специфика приложения.

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

Попробуй greenlets/gevent использовать вместо обычных тредов. Гуникорн умеет это из коробки.

provaton ★★★★★ ()
Ответ на: комментарий от provaton

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

У меня в принципе-то обычных страниц нет, один сплошной джаваскрипт. Динамические виджеты.

SOmni ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.