Как стать автором
Обновить

Комментарии 45

Расскажите пожалуйста, вы в чём-то выигрываете, вынося директорию проекта из директории виртуального окружения, или просто так карты легли?
Да как-то вообще мысли не приходило одно в другом держать
Тоже зачем-то раньше держал вложенный проект.
На нынешнем проекте, на dev-сервере приходится часто ставить в виртуальное окружение пакеты из trunk-ов, в такой конфигурации (с отдельными каталогами) гораздо проще тестировать.
А есть разница между «держать зачем-то» и «держать понятно зачем» %)
Замечу, в статье речь про готовый проект под конкретное окружение (читай «веб-сервис»), а не о приложении, на которое распространяется требование поддержки разных окружений, экземпляры которого уйдут клиентам. Вот последнее попадёт под описанную вами задачу, а для первого разделение излишне. В таком вот разрезе я об этом думаю.
Почему uWSGI а не fastcgi?
Я последний использую, может у первого есть какие-то скрытые преимущества? )
а у меня через supervisor
Релоад не только удобный, но и «graceful» (мягкий? вежливый?) — процессы не просто прибиваются и запускаются снова, старым процессам дается какое-то время чтобы обработать текущие запросы. В противном случае, если пользователю не повезло и его запрос обрабатывался как раз в момент перезапуска — он получит что-нибудь вроде 502 bad gateway.
Как реализовать graceful reload в случае fastcgi обсуждают, например, тут: stackoverflow.com/questions/361855/how-to-gracefully-restart-django-running-fcgi-behind-nginx
В смысле, у uwsgi — grceful reload. А у баш-скрипта на который вы ссылку дали — не очень :-)
Использую такую же связку, но uwsgi.ini лежит в каждом проекте в папке deploy/ и логи пишутся в deploy/var/log/uwsgi.ini — все файлы к текущему проекту находятся в проекте.
* deploy/var/log/uwsgi.log

И ещё у меня deploy/uwsgi.ini сам является целью для touch-reload.
> 1. Удобное управление запуском/остановкой/перезапуском нескольких проектов на одном хосте
Удобней работать с нескольикими проектами на одном хосте, когда:

1. каждый из их работает от отдельного пользователя
2. можно перезапускать один не трогая второй
3. каждый проект полностью изолирован (нельзя пользователем одного проекта, читать данные другого проекта).

Мне кажется, данная задача с вашим подходом вызовет некоторые трудности.

Я бы рекомендовал заменить uwsgi на (apache)mod_wsgi — значительно более стабильная и гибкая связка получится.
Держать монстра ввиде апача даже за nginx как-то совесть не позволяет. В чём проблема запускать uwsgi от разных пользователей? (у меня именно так и сделано) Все проекты изолированы и uwsgi конфиг лежит непосредственно в папке проекта и запускается от разных пользователей.
На счёт стабильности можно подробнее что-нибудь почитать кроме субъективного мнения? (у меня, например, ещё ниразу uwsgi не воткнул за полгода). И какая гибкость необходима, которую нельзя получить на uwsgi?
>Монстра ввиде апача.
apache? не знаю монтстр он или нет, но точно уверен: что mod_wsgi процесс apache-а очень лёгкий.

>В чём проблема запускать uwsgi от разных пользователей?
Раскажите как вы организовали:
1. автоматически старт при перезагрузке системы
2. логирование в /var/log (с logrotate-ом)

У нас на проекте, раньше использовался в различных местах и mod_wsgi и uwsgi, теперь переводится всё на mod_wsgi потому что стабильнее (uwsgi, supervisor у нас переодически отказывали).

>гибкость.
Всё что угодно, от ldap аутентификации, до webdav интеграции. Apache умеет очень много чего, а согласитесь, иметь и uwsgi и apache в production не логично.
1. Тут всё не очень хорошо — обычно просто дописыванием одной строки в /etc/rc.local, но всё хочу написать init.d скрипт, который будет стартовать все проекты…
2. logrotate — дописыванием инклуда в конфиг logrotate из deploy папки проекта.

Я согласен, что использовать и mod_wsgi и uwsgi неудобно и приходится выбирать. На счёт приведенных примеров гибкости — тут для меня всё просто, у меня подобных требований не было.
1. А если python процесс падает (а они иногда падают), как вы его перезапускаете?
2. А как вы сообщите процессу, что его log от rotate-ился? Rotate не такая простая операция. И я надеюсь вы таки сделаете запись log-ов в /var/log/, ибо backup-инг логов станная операция.

По мере реализации «cusmtom-ных» решений вокруг uwsgi я готов вам перечислять какие проблемы в вашей системе есть, которые уже давно решены в mod_wsgi apache-а.
1. Uwsgi супервизор ещё ниразу не падал, но на всякий случай стоит крон проверяющий жив ли супервизор.
2. postrotate
/usr/bin/kill -HUP `cat deploy/var/run/uwsgi.pid`

Я бы с удовольствием выслушал ещё предложения, вдруг я не всё учёл. Спасибо, за конструктивный диалог.
Собственно, причина, по которой я выбрал uwsgi — по тестам производительности в интернетах он выше mod_wsgi, плюс я не хотел тащить apache (просто субъективное мнение о нём сложилось). Сначала пользовался tornado как прокси, но вот ему точно не хватало стабильности и я начал искать что-нибудь с супервизором.
По всем тестам которые я видел, у uwsgi и mod_wsgi одинаковая производительность, пока тест не упрощается до return 200. — только тогда у uwsgi выше производительность. Локальное же тестирование показало, что абсолютно одинаковая производительность. Всё равно упирается именно в Python часть.

Что меня беспокоит в uwsgi-django-community, так это то, что все пользователи сами пишут пачечьку костылей (init.d скрипты/cron таски), для тех задач, которые весь мир давно считает решёнными.

Возвращаясь к 'init.d' скрипту — хотелось бы ещё увидеть, как вы в нём мульти-host-овость сделаете. Точнее так: считаю, что если в вашей системе для добавление очередного vhost-а, надо будет редактировать rc.local это будет не красиво.
'init.d' скрипт, скорее всего, я бы сделал какой-нибудь конфиг, где были бы перечислены просто директориии проектов, которые необходимо запустить, так как у меня все django-проекты имеют одинаковую структуру каталогов.

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

«пользователи сами пишут пачечьку костылей» — gentoo-way =)

Кстати, на счёт падений супервизора uwsgi, а как вы следите за тем, что апач не падает?
«Корневой» apache, тот который с uid=0, gid=0 — он не падает (вообще за ним админы следят какимии-то самыми обычными средствами). На нём же ничего не крутится никаких python-ов и т.д — вообще он очень стабильный и выверенный годами.

Падения свойственны уже python процессам, а у их ppid — apache. Собственно apache отлично следит за всеми своими детьми — опять же стабильный и выверенный годами подход.
> «пользователи сами пишут пачечьку костылей» — gentoo-way =)
Как человек который помнит установку gentoo ещё со stage1 — нет, это совсем не gentoo way.
Мир не без добрых людей, напомнили о Emperor режиме uWSGI.

Вкратце — создаю /etc/uwsgi/sites-enabled/ (просто ради единообразия с nginx) в эту папку делаем символьные ссылки всех конфигов проектов, которые нужно стартовать. После этого в rc.local или нормальным init.d скриптом вызываем одну команду:
uwsgi --emperor /etc/uwsgi/sites-enabled


PS Это всего лишь альтернативное, прозрачное решение относительно описанного метода автором статьи.
Делаю вывод, что статью вы не читали. Если бы прочитали, то увидели бы, что init-скрипт уже есть, что он при запуске поднимает все проекты, для которых найдет конфигурации в /etc/uwsgi/apps-enabled (на самом деле там симлинки на файлы конфигурации в /etc/uwsgi/apps-available), что любой проект можно запустить/остановить/перезапустить с помощью /etc/init.d/uwsgi start|stop|restart project_conf_name. И логи там ротейтятся, я вас уверяю. Как-то так вобщем
Статью читал, и даже запускал сам подобные конфигурации. Просто вы упустили очень важный (имхо) момент:

один instance uwsgi не позволяет запускать 2 проекта под различнными пользователями (разными uid и gid) — попробуйте настроить так 2 проекта. и вы увидите что uid и gid второго, переопеределяют 1й.

получается, всё равно надо запускать uwsgi отдельно для каждого проекта, а это уже идёт в разрез с вашей статьей.

Так для каждого проекта и запускается свой instance uwsgi. Где вы увидели противоречие эту в статье, я не очень понимаю
Покажите пожалуйста 2 проекта, запущенные от различный пользователей.
Пожалуйста! Молю.
example1.ini:
[uwsgi]
plugins = python27
virtualenv = /home/web/envs/example1/
chdir = /home/web/proj/example1/
pythonpath =…
env = DJANGO_SETTINGS_MODULE=example1.settings
module = django.core.handlers.wsgi:WSGIHandler()
uid = user1
gid = user1

example2.ini:
[uwsgi]
plugins = python27
virtualenv = /home/web/envs/example2/
chdir = /home/web/proj/example2/
pythonpath =…
env = DJANGO_SETTINGS_MODULE=example2.settings
module = django.core.handlers.wsgi:WSGIHandler()
uid = user2
gid = user2
Спасибо, а можно ещё init.d скрипт, чтобы debian не ставить?
Хотелось бы соотнести скрипт с конфигом.

И ещё один помент, как бы вы добавили в автозагрузку оба example-а.
Структура каталогов как в статье только для примера. Можно и по-другому организовать.
По пунктам:
1. Переопределяем uid и gid
2. Статья как раз об этом
3. А это решается правами на уровне файловой системы

А как в вашем подходе обеспечивается поддержка разных виртуальных сред для разных проектов?
Попробуйте запустить 2 проекта, с разными uid и gid, это возможно тока если uwsgi сам запускатеся от пользователя.
<VirtualHost *:8080>
ServerAdmin admin@example.com
ServerName site1.example.com

ErrorLog /var/log/httpd/site1_error.log
CustomLog /var/log/httpd/site1_access.log common

WSGIScriptAlias / /home/httpd/site1/app/wsgi/django.wsgi
WSGIDaemonProcess user=site1 group=site1 processes=2 threads=1
WSGIProcessGroup site1
WSGIApplicationGroup site1
WSGIPassAuthorization On

А вы не путаете виртуальные хосты с виртуальным окружением python (virtualenv)? Как мне помнится, virtualenv на весь апач может быть только один
Не путаю. virtualenv к apache-у вообще отношение не имеет, там несколько другая система взаимодействия.

1. В apache можно завести сколько угодно virtualhost-ов
2. На эти virtualhost-ы мы назначаем обработчиком mod_wsgi
3. Каждый mod_wsgi-virtualhost мы демоинизируем (при этом root-процесс apache-а остаётся «за главного»)
4. У mod_wsgi есть опция — wsgi скрипт запуска.
5. Ну а в wsgi скрипте вы уже можете извращаться как захотите, например настроить virtualenv
Мне не нравится в связке apache-mod_wsgi то, что используется интерпретатор питона из mod_wsgi, нельзя использовать версии питона из virtualenv. Если конечно, не ошибаюсь.
В этом наборе все хорошо кроме Debian. Увы эта ос уже не приоритет.
Что в альтернативе? просто уже около года использую связку nginx+uwsgi+supervisor+debian — проблем не было ни разу.
На вкус и цвет все фломастеры разные. У меня сервера и на CentOS, и на Ubuntu Server, и на Debian живут, я не сисадмин и мне привычнее debian-подобные системы, но всё-таки что сейчас «приоритет»?
Я использую centos. Сидел несколько лет на debian и freebsd. Позакрывал все эти сервера, перевел все на centos.
У меня еще вируталки на некоторых серверах, а для них centos то что доктор прописал.
А минусоидам — мне вас жаль ).
Пробовал) но люблю деплоить именно nginx + uwsgi ибо у nginx есть модуль для uwsgi, ну и uwsgi уже привычнее и больше с ним знаком — знаю почти от и до все что нужно и есть разные джанго пакеты для него(например django-uwsgi-admin) ну и как бонус — запускать rails через uwsgi и многое другое. Да и по производительности uwsgi оч хорош.
Как-то я делал набор скриптов, чтобы разворачивать хостинг для wsgi-приложений, написанных на pylons http://tinycode.ru/ubuntu-server-for-wsgi-with-pylons-nginx-uwsgi Только я сразу настраивал монит, чтобы он смотрел на всё это. Ещё на тот момент я не использовал virtualenv (сейчас использую, чтобы запускать на одном сервере pylons и pyramid)
Я тоже деплою через nginx + uwsgi но у меня чуть иначе:
есть свой стартовый джанговский проект в котором переделанный под меня django-config-gen он сразу генерит нужные мне конфиги согласно настройкам и кладет куда надо:
/etc/init/project_name.conf примерно такого содержания:
description "uWSGI server for Project project_name"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /server/env/bin/uwsgi -p 2 --uid mechanism --home /server/env/ --socket /server/sock/project_name.uwsgi.sock --chmod-socket --module runsite --pythonpath /server/SITES/project_name --daemonize /server/log/project_name.uwsgi.log

упомянутый runsite.py выглядит примерно так:
import os, sys
current_directory = os.path.dirname(__file__)
parent_directory = os.path.dirname(current_directory)
module_name = os.path.basename(current_directory)
sys.path.append(parent_directory)
sys.path.append(current_directory)
os.environ["CELERY_LOADER"] = "django"
os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % module_name
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

«Почему uWSGI а не fastcgi?
Я последний использую, может у первого есть какие-то скрытые преимущества? )»

в зависимости от требований проекта могут добавляться: --enable-threads --loop gevent --async 100 и уже в джангу можно добавлять например gevent

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

Публикации