Pull to refresh

Comments 56

Буквально на прошлых выходных поднимал сайт на подобной связке: Nginx + uWSGI + Django + Daemontools

У меня возникла одна проблема: запущенная демоном джанга на отрез отказывается загружать изображения с кириллическими названиями, вываливая ошибки юникода. При том, если запустить сервер от текущего пользователя root'a или от user — все ок.
# uwsgi -s /tmp/uwsgi.sock --uid 1000 -x /usr/local/www/webapp.xml

Как только сервер запускается демоном — проблема :(
# svc -u /etc/service/site

Пробовал через /etc/inittab — результат один.
Вопрос решил пока методом нанотехнологий, сделав кастомный путь для upload_to
filename = pytils.translit.translify(filename)

Кто-нибудь встречался с такой проблемой?
Debian 6. У пользователя uid1000 и у рута — ru_RU.UTF-8. Django 1.3
dpkg-reconfigure locales мне помогло в аналогичной ситуации
Да, уже выполнял ее. Ребутнулся, чтобы наверняка. Попытался залить файл с кириллическим названием, сервер упал, а я получил на почту:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 61-66: ordinal not in range(128)

~# locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

Ладно, буду дальше думать
может у вас в каком-то скрипте эти имена файлов явно используются, а кодировка в начале скрипта не указана?
# -*- coding: utf-8 -*-
ленивые люди которым не хочется при каждом деплое копировать/править сотни файлов, выносят все что у вас в app1 в uwsgi.xml и вроде мастер процесс не работает с один воркером, но могу ошибаться
я не совсем понял, в статье вы называете app1,app2, appN разные проекты или разные приложения одного проекта? если второе то поясните суть такого велосипеда.

у меня сейчас та же связка настроена в виде 3 файликов: project-name.com(в sites-enabled нгинкса), django.xml в корне проекта и стандартного стартового скрипта project-name(которые живут в /etc/init.d и позволяют стартовать, останавливать, рестартить конкретный проект). Уже наверно с полгода как хотел написать на хабр, но теперь вот сомневаюсь нужно ли.
Хех) Опередил меня) ^_^
Имеются в виду именно разные проекты — «конгломерат Django-приложений». Жаль что не написали, сэкономили бы мне время ) А содержимое location'ов nginx у вас такое же, или вы делаете как-то по другому?
Джанго-проекты собираются из одного и более приложений, поэтому хорошо бы для внесения ясности заменить слово «приложение» словом «проект», а app{x} сменить на djprj{x}.
как уже заметил idle в джанго обычно 1 проект состоит из одного или более приложений которые связаны между собой на уровне джанги, а не вебсервера. Примерно так выглядит обычный проект:
djangoproject
--app1
--app2
--appN
--media
__init__.py
manage.py
settings.py
urls.py
а у вас получается подмена понятий привычных джангисту:) Еще у вашего способа минус — если нужно перезапустить 1 проект, вы вместе с ним перезапустите остальные.
На счет location'ов: у меня uwsgi_params общие инклудятся в каждом хосте, остальные берутся с xmlки проекта. также на каждый проект логи ведутся отдельно в папке проекта, тамже живет сокет и pid файл для управления проектом, также указана раздача статики(и время на которое ее кешировать) для проекта и админки. Естественно на каждый проект свой процесс uwsgi со своими настройками(количество воркеров, логи, файл настроек проекта, юзер и група от которой запускается процесс). управляется проект стандартным скриптом(projectname start|stop|reload), отдельно от nginx который работает постоянно.
Спасибо idle, FeNUMe, исправил Django-приложение, на Django-проект.

«Еще у вашего способа минус — если нужно перезапустить 1 проект, вы вместе с ним перезапустите остальные.» — Да, тут я с вами абсолютно согласен, но для решаемых мной задач это абсолютно не критично. Что касается способа запуска, который используется у вас, он как раз и является каноническим )
а что вас заставило пойти другим путем? какие плюсы вашего способа? я вижу только уменьшение количества процессов uwsgi, но это очень сомнительный плюс учитывая общий перезапуск проектов и падение всех проектов одновременно в случае сбоя/ошибок.
Мне не хотелось колхозить стартовые скрипты для запуска на каждый django-проект, а запускать все традиционным для FreeBSD способом через rc.conf. Опять таки, уменьшить количество webapp.xml файлов, но это 10е, а то и 100е дело.

Если бы FreeBSD имела возможность запуска «управляется проект стандартным скриптом(projectname start|stop|reload)», то я бы выбрал его из соображений атомарности и автономности воркеров/проектов. Но FreeBSD не имеет такой возможности, поэтому я пренебрег этим.
можно сделать

cd /usr/local/etc/rc.d
perl -pe 's/(["{ ])uwsgi/$1your_project/g' uwsgi > your_project
chmod +x your_project

и скрипт готов
Это как раз и есть тот колхоз, который мне бы не хотелось разводить в стартовых скриптах ) В данный момент, версия uWSGI 0.9.7.2 не позволяет использовать предложенный мной вариант, ведет себя аномально. Сейчас посматриваю в сторону Emperor.
Не понял, зачем приложения в location'ы nginx'а выносить? Разные django-проекты на одном сайте?.. Смысл?.. А если это действительно приложения, то почему не в urls.py??? Мне кажется что я что-то не понимаю.
Вы возможно правы, с Django работаю исключительно как системный администратор, мне дают каталог с Django-приложением и говорят — «надо»! «Разные django-проекты на одном сайте?.. Смысл?» — а почему бы и нет? Отдельные задачи, отдельные Django-проекты.
Как раз думаю как развернуть подобное на своем серваке для тестов :) Спасибо)
UFO landed and left these words here
У меня сейчас все проекты работают на Tornado. Когда-то смотрел бэнчмарки и тестировал в связке с django, получались результаты абсолютно не совпадающие с бэнчмарками, поэтому хотел бы узнать у Вас, %habrauser%, что лучше использовать uWSGI или Tornado? Или может вообще третий вариант?
Tornado с django внутри запустить, безусловно, можно, но смысла в этом почти нет — Tornado подразумевает быстрые неблокирующие процессы. В случае с «hello, world», которым обычно пишут бенчмарки, производительность пронзает небеса, но как только django обратится к MySQL и будет ждать от нее ответа, вместе с ним будет ждать ответа Tornado и все остановится.
Кто может подсказать, чем flup (fastcgi + nginx) в случае джанги хуже wsgi + nginx?
как минимум в скорости, причем в разы. в нете хватает сравнительных тестов, хоть большинство из них не совсем верны(не охватывают все возможные нагрузки), но примерно позволяют сравнить скорости. Я когда на локальном тестовом сервере(со слабым железом) перешел с flup на uwsgi разницу заметил глазом без каких либо тестов. к сожалению с работающего проекта статистику привести не могу.
Допустим, джанга может отдавать 25-50 страниц в секунду (реальный проект, много динамики).
Каким образом тут понизится скорость отдачи из-за nginx-а?
если у вас проект такой что производительность упирается в джангу, то конечно скорость не изменится какой бы вебсервер и прослойку(flup,uwsgi...) вы не использовали. Но я бы на вашем месте задумался о оптимизации проекта, например кешировании, а то 25-50 реквестов в секунду это мало. я конечно не спец, но посмотрите популярные проекты на джанге, тотже disqus или сервисы яндекса — там тысячи запросов в сек обрабатываются… возможно что у вас тормозит не сама джанга, а получение данных из бд
Вы бы еще с твиттером сравнили, у которого фронтенд на рельсах. У дискасса вообще-то очень хорошая распределенная инфраструктура с сотней машин.

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

Но я бы на вашем месте задумался о оптимизации проекта

Все дерганья базы отпрофилированы и отполированы до блеска.
например кешировании
А разве какой-то серьезный проект сегодня без него обходится?

25 реквестов в секунду это 2 млн в сутки и 60млн в месяц, соответственно, 50 реквестов — это уже 120млн. Это НЕ мало. StackOverflow и ВСЯ его инфраструктура (46 сайтов) собирают 96млн просмотров в месяц. А мы говорим про одну обычную машину, а не про двадцать-тридцать мощнейших серверов у stackoverflow.
значит я не прав, бывает. может поделитесь более подробно инфой на чем у вас этот проект работает, сколько ресурсов жрет?
Замеры я проводил давно, но, насколько я помню, при нагрузочном тестировании все кушало около трехсот-четырехсот мегабайт ОЗУ. На CPU тоже нагрузка была маленькой.
Самое большое, что джанга выдала тогда это 300rps на очень простой странице API (тоже полная динамика).

Python 2.7 + MySQL + Django + FastCGI + Flup -> nginx.
Есть ли способ в этой связке заставлять Django релоадить изменения кода без перезапуска сервисов?
а зачем? чтобы случайно отдавать клиентам код который работает с непредназначеной для него схемой БД?
Чтобы не просить админов сделать /etc/init.d/apache2 reload, если прав нет.

Мне кажется самым удобным подход, принятый в wsgi: обновление кода происходит при изменениях даты модификации файла, через который подключен проект. То есть, можно заливать новые файлы проекта, а в нужный момент просто сделать touch django.wsgi.
мне как то kill -1 удобнее или restart service name, если админы не могут настроить все для удобного деплоя — зачем они нужны :)
Можно также добавить в /etc/sudoers
username ALL = NOPASSWD: /usr/sbin/service apache2 reload
Я тоже раньше использовал nginx. Потом сел настраивать связку с django uwsgi и daemon tools.
Теперь я использую Cherokee. Его основное достоинство в таком сетапе — он сам умеет запускать uwsgi демоны. daemontools ненужен! Очень удобно.

Добавьте сюда web админку, скорость работы сравнимую с nginx.
Я тоже поставил для эксперимента Cherokee. Радует что он сам «присматривает» за uwsgi и flup демонами и довольно удобно админится.

Хотя, если честно, для чего-то большого использовать его пока не решаюсь.
Спасибо, недавно поднимал django сайт на apache + mod_wsgi, не все мне понравилось, теперь в следующий раз такой попробую.
UFO landed and left these words here
Куча дополнительных неочевидных настроек + я это на генту делал, там очень френдли коммьюнити — по любому вопросу отправляют хендбук читать. Сейчас уже подробнее не вспомню…
UFO landed and left these words here
Спасибо, я когда ставил — весь интернет перечитал. Для генту многое не работало. В итоге родилась эта статья — и я для себя решил, что не хочу больше на генту ничего ставить. А настройки — это всякие портежи, замаскированные пакейджи, нежелание добавлять пути в PYTHONPATH из wsgi скрипта для почти всех юзеров (в т.ч. и для того, под которым апач работает) и прочее.
UFO landed and left these words here
Хм… Я ставил uwsgi в Ubuntu из PPA ppa.launchpad.net/uwsgi/release/ubuntu

Там довольно интересно сделано по умолчанию… Для перезапуска всего uWSGI командуем
sudo service uwsgi-python restart
а для перезапуска конкретного проекта
sudo service uwsgi-python restart project_name.
Второй вариант рестартует только воркеров, относящихся к проекту project_name.

uWSGI конфиги проектов лежат в /etc/uwsgi-python/apps-available/ и /etc/uwsgi-python/apps-enabled/

Ну и, соответственно, хитрый init скрипт который это обрабатывает и сканирует /etc/uwsgi-python/apps-enabled/ на предмет наличия конфигов.
а вы ставили uwsgi-python2.6 или uwsgi-python3.1? у меня из этой же ppaшки стоит 0.9.6.5-0ubuntu1 uwsgi-python2.6 и нет даже таких каталогов, не то что сервиса. а стандартный стартовый скрипт умеет брать конфиги проектов из /etc/uwsgi/uwsgi-python2.6 при старте, но управлять воркерами после запуска уже не умеет.
seriy@seriyps:~$ aptitude search uwsgi
p   libapache2-mod-ruwsgi                                                  - uWSGI module for Apache2 (mod_Ruwsgi)                                            
p   libapache2-mod-uwsgi                                                   - uWSGI module for Apache2 (mod_uwsgi)                                             
p   python-django-uwsgi-admin                                              - Django application for administering uWSGI server                                
p   uwsgi                                                                  - fast, self-healing, developer-friendly WSGI server                               
i A uwsgi-common                                                           - fast, self-healing, developer-friendly WSGI server (common files)                
p   uwsgi-extra                                                            - fast, self-healing, developer-friendly WSGI server (extra files)                 
p   uwsgi-plugin-lua                                                       - Lua WSAPI plugin for uWSGI                                                       
p   uwsgi-plugin-psgi                                                      - Perl PSGI plugin for uWSGI                                                       
p   uwsgi-plugin-rack                                                      - Ruby Rack plugin for uWSGI                                                       
p   uwsgi-plugins-all                                                      - all available plugins for uWSGI                                                  
i   uwsgi-python                                                           - fast, self-healing, developer-friendly WSGI server (Python 2)                    
p   uwsgi-python-dbg                                                       - debugging symbols for uWSGI server (Python 2)                                    
p   uwsgi-python2.6                                                        - dummy package to ease transition to uwsgi-python                                 
p   uwsgi-python3                                                          - fast, self-healing, developer-friendly WSGI server (Python 3)                    
p   uwsgi-python3-dbg                                                      - debugging symbols for uWSGI server (Python 3)                                    
p   uwsgi-python3.1                                                        - dummy package to ease transition to uwsgi-python3 
                               
seriy@seriyps:~$ aptitude show uwsgi-python
Package: uwsgi-python
New: yes
State: installed
Automatically installed: no
Version: 0.9.6.8-0ubuntu1~uwsgimaintppa1~lucid1
Priority: optional
Section: web
Maintainer: Leonid Borisenko <leo.borisenko@gmail.com>
Uncompressed Size: 434k
Depends: libc6 (>= 2.7), libldap-2.4-2 (>= 2.4.7), libpcre3 (>= 7.7), libpython2.6 (>= 2.6), libsctp1 (>= 1.0.10+dfsg), libxml2 (>= 2.7.4), uwsgi-common (=
         0.9.6.8-0ubuntu1~uwsgimaintppa1~lucid1)
Suggests: libapache2-mod-uwsgi | libapache2-mod-ruwsgi, uwsgi-plugins-all, uwsgi-extra
Conflicts: uwsgi (< 0.9.6.8-0ubuntu1~uwsgimaintppa1~maverick1)
Breaks: uwsgi-python2.6 (< 0.9.6.8-0ubuntu1~uwsgimaintppa1~maverick1)
Provides: httpd-wsgi, uwsgi-python2.6
Description: fast, self-healing, developer-friendly WSGI server (Python 2)
 uWSGI is aimed for professional Python webapps deployment and development. Over time it has evolved in a complete stack for networked/clustered Python
 applications, implementing message/object passing, RPC, process management and a plugin loading technology that can be used to add support for other
 languages or platform. 
 
 This package provides uWSGI for serving on Python 2.X.

seriy@seriyps:~$ dpkg -L uwsgi-python
/.
/etc
/etc/init.d
/etc/init.d/uwsgi-python
/etc/default
/etc/default/uwsgi-python
/etc/uwsgi-python
/etc/uwsgi-python/apps-enabled
/etc/uwsgi-python/apps-enabled/README
/etc/uwsgi-python/apps-available
/etc/uwsgi-python/apps-available/README
/etc/logrotate.d
/etc/logrotate.d/uwsgi-python
/usr
/usr/bin
/usr/bin/uwsgi-python2.6
/usr/share
/usr/share/doc
/usr/share/doc/uwsgi-python
/usr/share/doc/uwsgi-python/README.Debian.gz
/usr/share/doc/uwsgi-python/copyright
/usr/share/doc/uwsgi-python/uwsgi-python.init.d.custom.gz
/usr/share/man
/usr/share/man/man8
/usr/share/man/man8/uwsgi-python2.6.8.gz
/usr/share/python
/usr/share/python/runtime.d
/usr/share/python/runtime.d/uwsgi-python.rtupdate
/var
/var/log
/var/log/uwsgi-python
/usr/share/doc/uwsgi-python/README
/usr/share/doc/uwsgi-python/changelog.Debian.gz
/usr/share/doc/uwsgi-python/changelog.gz
/usr/share/doc/uwsgi-python/tests
/usr/share/doc/uwsgi-python/examples


т.е. видимо у меня uwsgi-python2.6 и версия 0.9.6.8
нашел в чем разница у меня репозиторий ppa.launchpad.net/uwsgi/uwsgi/ubuntu и пакет стоит просто uwsgi, а у вас uwsgi-python из ppa.launchpad.net/uwsgi/release/ubuntu. попробую ваш вариант, хоть он и не сильно отличается от того что использую сейчас, но намного удобнее когда все уже сделано за тебя из коробки:)

эх наверно пора переставить софт на серваке с нуля, а то живет с 8.04 — хрен знает сколько таких вот устаревших репов там уже.
Тема интересная, но автор так торопился, что обрезал конфиг нджинкса по непонятной схеме.

Вот статья китайского брата, которая помогла мне. www.indexofire.com/blog/?p=741
Что именно Вам непонятно в «обрезанном конфиге нджинкса»?
UFO landed and left these words here
# -*- coding: iso-8859-1 -*-
import sys, os
import django.core.handlers.wsgi

sys.path.insert(0, '/usr/local/www/app1')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

application = django.core.handlers.wsgi.WSGIHandler()

Это точка входа в Django проект.

А как быть если проект Flask?
И запускается с помощью файла myapp.py в корневой папке проекта.
Боюсь что если я добавлю app и myapp в webapp.xml то остальные Django проекты которые я буду добавлятьЮ,

Боюсь, что если я добавлю app и myapp в webapp.xml то остальные Django проекты которые я буду добавлять не будут запускаться. *
Уважаемые, теме более полугода, все уже давно изменилось. Используйте появившиеся в uwsgi фичи, они прекрасно дружат с flask'ом, django и самим python'ом.
Only those users with full accounts are able to leave comments. Log in, please.