Pull to refresh

Comments 54

тока не пип инсталл увсги
а апт-гет инсталл увсги… (ну или йум… как там дальше)
Нет, потому что используется virtualenv.
А pip разве не умеет ставить system-wide?
pip умеет, но вот этого как раз лучше не делать. Для системного софта — системный менеджер пакетов.
Нет. Именно pip глобально. В пакетах обычно довольно старая версия.
Нет. Если версия в пакетах не устраивает, собираем актуальную в пакет и его ставим. Никакого глобального пипа.
Оч хороший вариант. Я иногда и целые джанго проекты запихивал в .deb-ки и деплоил через apt)
Еще как вариант установить uwsgi в какое-то отдельное виртуальное окружение и просто оттуда его вызывать /path/to/virtualenv/bin/uwsgi или с помощью github.com/jsvine/envplus который может одно вирт окруж комбинировать с другими. У меня например есть окружение со всем связанным с postgresql там и psycopg2 и всякие django-hstore итд, и я чтобы при разработке не ставить все лишний раз в новое окружение просто прописываю envplus add имя_нужного_окружения(ну естественно я заблаговременно подготовил несколько тематических окружений по разным нуждам и систематически обновляю в них пакеты)
Мне вот другое интересно, а насколько сейчас актуально uWSGI? Последнее время везде вижу Django + Gunicorn. И всё это управляется через supervisor.

В чём принципиальная разница между этими двумя подходами, что работает эффективнее и т. п.?
Гуглил тесты — по ним uwsgi несколько быстрее получается. С другой стороны, gunicorn отдает готовый http, и если статику вынести на s3 или в cdn, то на веб-воркере можно вообще без nginx обойтись.
Нельзя. Gunicorn плохо предназначен для того, чтобы смотреть в мир, и в итоге вы получите Apache со всеми его проблемами.
Не «в мир», а на лоад-балансер, скорее. Правда, nginx на балансере так же может проксировать запросы и на uwsgi, так что это и правда так себе аргумент.
Так uwsgi тоже сам умеет по http разговаривать. Ичо?

gunicorn уже починил проблему межденных соединений (когда ответ tcp тянут по одному байту в пол-часа, чем забивают всех имеющихся воркеров и получают dos)?
Выше обсудили уже — да, совсем наружу этот 80 порт выставить все равно не получится.
Спорный вопрос. uWSGI emperior мне показался более удобным в плане деплоймента. Принципиальная разница в том между nginx и uwsgi демоном данные уже обработаные бегают отсюда небольшой выигрыш.
Запускать лучше специально сделанной для этого тулзой типа supervisor-а.

Еще есть мнение, что процессы в uwsgi работают не очень хорошо, и лучше руками запускать Х процессов uwsgi, а балансировку делать nginx-ом.
Полностью поддерживаю вариант с supervisor. 2 года в проде на этой схеме.
Я бы таки рекомендовал Gunicorn вместо uWSGI, как более простое и стабильное решение.
Огромный плюс uWSGI в том, что его можно использовать для развёртывания приложений как Python/WSGI, так и Ruby/rack, а также PHP и многих других. Причём uWSGI предоставляет богатые средства интеграции этих веб-приложений, конфигурирования их в общем стиле и т.д. В общем, проект амбициозный, с очень широким функционалом, рекомендую почитать документацию.
Рекомендую почитать исходники uWSGI. ;)
Использую похожую связку, только в ней присутствует ещё и supervisor
так как у вас в ini-конфиге уже прописана chdir
chdir = /path/to/your/project
то ниже не стоит лишний раз прописывать пути, можно просто добавить %(chdir) вместо "/path/to/your/project":
socket = %(chdir)/mysite.sock
так-же можно назвать uwsgi.ini с именем проекта project.ini и в конфиге %n будет означать имя файла конфига до расширения то есть project
я все-же чаще называю его uwsgi.ini, но имя проекта чтобы не писать постоянно просто берется из имени директории в которой лежит файл конфига — %c
Подробнее смотреть тут.
Например у меня в конфиге сокет так прописан: socket = %d%c.uwsgi.sock — %d полный путь до папки в которой лежит конфиг, %c имя директории проекта.
Тоже самое с module = %c.wsgi

часто у меня в конфиге uWSGI несколько секций, одна общая откуда другие при необходимости берут эти общие дефолтные настройки типа:
[uwsgi]
uid = server
gid = server
chmod-socket = 664
chown-socket = server:server
 
;тут типа настроено так что виртуальное окружение имеет такое-же имя как и имя проекта
venv = /server/.virtualenvs/%c
pp = %d
master
processes = %k
cheaper = 4
protocol = uwsgi
autoload
no-orphans
memory-report
die-on-term
harakiri = 60
harakiri-verbose
reload-mercy = %k
worker-reload-mercy = %k
max-requests = 5000
buffer-size = 65535
post-buffering = 1048576
reload-on-rss = 300
touch-reload = %p
vacuum
 
enable-threads
single-interpreter
lazy-apps
 
; читаем .env файлы которые совместимы с foreman/honcho например как для хероку, всякие настройки в переменных окружения.
for-readline = .env
  env = %(_)
end-for


а ниже например могут быть секции типа таких:
[stats]
stats = %d%c.uwsgi.stats.sock
stats = :1717
[cache]
cache = 1000
cache-blocksize = 65536


или:
[development]
print = Hello I'm the %x config for %c django project %X!
ini = :uwsgi
ini = :staticfiles
procname-master = [uWSGI Master for %c app Dev]
procname = [uWSGI Worker for %c app Dev]
socket = %d%c.uwsgi.sock
module = %c.wsgi
logto = %dlogs/%c.uwsgi.%x.log
py-autoreload = 2


тут например видно что в местах
ini = :uwsgi
ini = :staticfiles
подхватывается конфиг из других секций.

py-autoreload = 2 — отличная штука — uWSGI автоматом перезагружается при разработке как и джанговский девелопмент сервер после изменения файлов.

так-же при разработке или например на хероку можно использовать что-то типа:
[staticfiles]
static-map2 = /assets=%dpublic
static-map2 = /uploads=%dpublic

Тут предполагается что папка public лежит в корне проекта, а в ней assets как static и uploads как media
а в settings.py например так:
STATIC_URL = '/assets/'
STATIC_ROOT = cd('public/assets')
MEDIA_URL = '/uploads/'
MEDIA_ROOT = cd('public/uploads')

тогда uWSGI вообще можно использовать без nginx(если есть необходимость) и он вообще вполне сносно раздает статические файлы.

вот например один из моих Procfile:
web: newrelic-admin run-program uwsgi uwsgi.ini:development
ws: newrelic-admin run-program uwsgi uwsgi.ini:websocket

Тут сразу становится понятно как запускать нужную секцию, в которой вы сделали импорты других нужных вам секций.

Незнаю почему вообще сравнивают uWSGI и Gunicorn. uWSGI намного более функциональный — он может выступать и как замена celery/rq(я через uwsgi spooling и почту рассылаю пачками и другие фоновые задачи выполняются), он может мониторить файлы, папки, как крон работает и много чего еще… отлично ладит с nginx и с кэшем удобно работать. uWSGI и просто как wsgi сервер уже на голову выше Gunicorn, и делает много, надежно, быстро(ну явно быстрее чем Gunicorn), и при этом кушает не так много. А если вспомнить о всех вкусностях которые хранятся в закромах uWSGI то вообще даже и смотреть не хочется на Gunicorn
Я вот немного попиливаю github.com/unbit/django-uwsgi но все с временем проблемы, в планах много всего и многое под разные проекты делалось а выпилить и оформить с доками в ту репу все что-то никак. Еще по теме uwsgi есть django-uwsgi-mail и django-uwsgi-cache

Забыл еще упомянуть что можно вообще весь ваш проект скормить в uwsgi и запускать типа ./myapp --no-site --master --processes 4, там как-раз и понадобится TemplateLoader из django-uwsgi
Забыл упомянуть про emperor и свою структуру проектов.
например у меня в каждом django-проекте лежит nginx.conf и uwsgi.ini
в основном nginx.conf прописывается:
include /server/apps/*/nginx.conf;
а при запуске uwsgi в режиме emperor:
newrelic-admin run-program uwsgi --emperor="/server/apps/*/uwsgi.ini:production"
это упрощенно а так-то у меня и для emperor .ini файлик есть с настройками и для вассалов всякие по умолчанию настройки.
По сути nginx ищет свои конфиги в /server/apps/любое имя проекта/nginx.conf — конкретно ищет nginx.conf
и тоже-самое с uwsgi
Еще в плане сравнения uWSGI c Gunicorn — Gunicorn не умеет сервить Ruby, PHP, Perl и другие проекты, а uWSGI легко.
А nginx.conf и uwsgi.ini конкретно проекта находятся в его репе или вы их отдельно кладёте в проект? Интересует, насколько это удобно/гиморно держать конфиги веб-сервера в репе проекта.
Конфиги nginx.conf и uwsgi.ini касающиеся проекта лежат в репе с проектом конечно если проект изначально заточен под полное взаимодействие с nginx и uwsgi(например кеширование и многое другое там прописано и у каждого проекта могут быть нюансы к примеру какой-то проект может использовать что-то типа django-nginx-image)
Посмотрите на репозиторий проекта rtfd.org — там вообще вроде как немеряно конфигов nginx валяется, если что-то не изменилось.
А вот такой пример. У нас куча проектов, запущенных через emperor mode. Мы хотим временно остановить какой-нибудь проект. Что делать? Я обычно просто убираю ini файл в каталог disabled, но у меня все uwsgi ini файлы сайтов в одном месте лежат. А если эти ini файлы будут в репозиториях, получается, эта операция будет затрагивать репозиторий.
Ну тут все зависит от конкретного проекта и причин почему его нужно остановить. Так-то способов остановить конкретного вассала не мало)
Вообще по-хорошему так бд и файлопомойка должны быть вообще на другом сервере а проект который нужно именно остановить (а не перезапустить или еще что-то) бы вообще оттуда снести и потом когда надо снова задеплоить из репы и все.
А как можно остановить вассала, без физического удаления конфиг-файла из директории, за которой наблюдает император?
Если у вас есть необходимость останавливать какого-то вассала, а проектов прямо куча, то уже только ради удобства использования я бы советовал вам держать конфиги вассалов например в mongodb или в postgresql. если вассала из бд удалить или пометить неактивным — процессы этого вассала останавливаются, при добавлении в бд нового вассала или если пометить его активным — автоматом стартуют. У меня в планах было сделать простенькую админку для таких целей в рамках django-uwsgi чтобы через нее можно было править конфиги и перегружать вассалов и поддерживать все возможные способы чтения конфигов у uwsgi
P.S. все равно считаю что хранить конфиги в репе очень желательно, при деплое например их использовать или нет — дело десятое, но хотябы в качестве примера работающего если вдруг срочно надо будет составить конфиг под конкретно этот проект а сисадмина или кого-то еще рядом нет…
Скопипастил конфиг из репы, ввел имя конфига и расширение и заполнил другие поля, в бд сохранил и процессы вассала запустились.
Так вроде бы уже сделано:
"""
Django-uWSGI Features:
Admin page with uWSGI stats (options to reload/stop uWSGI, clear uWSGI cache)
"""

(сам ещё не пробовал)
Так там просто выводится статистика именно того uwsgi под которым работает эта админка. Там грубо говоря просто статистика и возможность перегрузить а нет возможности создать нового вассала или поменять его конфиг.
Выше же я имел ввиду сделать что-то типа админки для управления сразу всеми вассалами — типа что-то типа панели хостера например, где ты видишь все запущенные вассалы и можешь ими рулить.
Одно время пользовался spooler. Не устроило например что по touch-reload процесс spooler так же рестартует и если в этот момент выполнялась какая-то фоновая задача — её выполнение прерывалось. Как поменять поведение не нашел (если это вообще было возможно).
Спасибо, добрый человек, за это:

uid = user
gid = user
chown-socket = www-data:www-data


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

Получал ошибку:

attempt to write a readonly database
Почему все мануалы на эту тему забывают --plugin python --plugin http?

Или это исключительно особенности новой убунты, что плагины не цепляются итз коробки?
а потому что по умолчанию uwsgi уже собирается с этими модулями и не нужно ничего прописывать.
если вы пробовали ту uwsgi которая ставится через apt — так там модульная сборка которая расчитана на легковесность(только в конфиге подключаются нужные модули и они уже отдельными файлами лежат например в папке plugins а не встроены в бинарнике uwsgi). я всегда ставлю uwsgi через pip, а если нужен какой-то особенный профиль сборки просто подставляю нужные параметры например: UWSGI_PROFILE=gevent pip install uwsgi тогда uwsgi установится сразу еще и с плагином gevent и его не надо прописывать как plugin а просто сразу в конфиге использовать. Если ставить uwsgi через pip там же после установки указано какие плагины скомпилились вместе с uwsgi.
Тут можно посмотреть на конфиги разных профилей))
Кто-нибудь кроме меня запускает uWSGI через upstart? Без supervisor / uWSGI Emperor…
Я запускаю чаще через upstart в том числе с Emperor
рекомендуется использовать Unix-сокет из-за преимущества в производительности.

мифического преимущества. датаграммы проигрывают tcp из-за дропов в очереди и отсутствии бэклога принятия соединений, а тут ещё и даже вопрос не ставится об увеличении длины очереди датаграмм
Unix-сокет != датаграммы

Вы всё напутали.
Бес попутал, простите.
Очереди приёма соединений всё равно так и нет.
Да ладно, как же без очереди соединения то с одного сокета разбирать: net.core.somaxconn!? =)
У unix-сокетов нет syn-бэклога (tcp_max_syn_backlog), по очевидным причинам. Ну так оно им и не нужно.
А как сделать чтобы в конце порт не нужно было прописывать?
То есть чтобы сайт был доступен не по:
http://yourserver.com:8000/
А по:
http://yourserver.com/

Спасибо.
Вместо 8000 используйте порт 80.
Дошел до момента с запуском через «ini» файл. Последний удачный запуск через «socket» удается только с правами «666» вот так:
uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666
Пытаюсь запустить через ini файл:
uwsgi --ini mysite_uwsgi.ini
и выдает ошибку:
...
current working directory: /home/user/.virtualenvs/uwsgi-tutorial/mysite
detected binary path: /home/user/.virtualenvs/uwsgi-tutorial/bin/uwsgi
chdir(): No such file or directory [core/uwsgi.c line 2537]
chdir(): No such file or directory [core/uwsgi.c line 1565]

В чем может быть проблема? Конфиг такой:
[uwsgi]
plugins = python27
harakiri = 60
chdir = /home/user/.virtualenv/uwsgi-tutorial/mysite/
module = %(chdir)/mysite.wsgi
home = /home/user/.virtualenv/
socket = %(chdir)/mysite.sock
master = true
processes = 10
vacuum = true
uid = www-data
gid = www-data
chmod-socket = 666
chown-socket = www-data:www-data
[development]
py-autoreload = 2
Поясните, почему у вас в сообщении uwsgi — /home/user/.virtualenvs/uwsgi-tutorial, а в конфиге — /home/user/.virtualenv/uwsgi-tutorial (без s)? Может быть, в этом дело? Какой путь на самом деле?

Во-вторых, возможно, у вас уже есть файл %(chdir)/mysite.sock? От какого пользователя вы запускаете указанную команду, кто является владельцем %(chdir) (и какие на ней права)?

Ну и я ещё не понимаю, зачем вам этот virtualenv прятать. У меня они называются по смыслу проектов, для которых сделаны, или по набору софта в виртуалэнве: ~/py32d16, например, а там python3.2 и установлена django 1.6.

Схему, подобную описанной в топике, применил ещё задолго до его описания, в то время и django 1.4 только выходил. uwsgi у меня запускается от имени того пользователя, чей это homе, т.е. конфиг имеет вид
[uwsgi]
chdir = /home/merlin/ac1532.office.rterm.ru
socket = %(chdir)/ac1532.uwsgi
plugin = python32
pyhome = /home/merlin/django15python32
module = ac1532.wsgi
chmod = 666
master = 1
workers = 8
cheaper = 2
idle = 30
procname-master = uWSGI master
procname-prefix-spaced = ac1532
logfile-chown = 1
daemonize = %(chdir)/logs/uwsgi_log
pidfile = %(chdir)/ac1532.pid
vacuum = 1
uid = merlin
gid = merlin

это работает из uwsgi emperor, в котором включен режим тирана и он таким образом запускает мастер-процесс с этим ini-файлом от имени merlin:merlin.
Спасибо, во всем разобрался. По мимо ошибок в путях были еше проблемы с правами.
Сколько соединений одновременно поддерживает Django в режиме разработки, если его сразу деплоить, без WSGI сервера?

Для людей с ошибкой (13: Permission denied) и не хотящих давать права 666: эта статья - перевод с английского. В оригинале решение проблемы описывается так:
You may also have to add your user to nginx’s group (which is probably www-data), or vice-versa, so that nginx can read and write to your socket properly.

Если коротко - не только нужно добавить своего пользователя в группу www-data, так же нужно добавить пользователя www-data в группу своего профиля (совпадает с username). Мне помогло.

Only those users with full accounts are able to leave comments. Log in, please.