Apache с поддержкой mod_python на текущий момент является наиболее стабильной и надёжной средой при развёртывании Django на рабочем сервере.
mod_python (http://www.djangoproject.com/r/mod_python/) — это модуль для Apache, позволяющий встроить Python в ядро Apache и загрузить программы на Python в память веб сервера при его запуске. Исполняемый код хранится в памяти до конца работы процесса Apache, что дает значительный прирост производительности.
Для работы Django необходим Apache версии 2.x и mod_python версии 3.x, в качестве МП-модуля рекомендуется использовать Prefork, а не Worker.
Замечание
Обсуждение настройки Apache выходит далеко за рамки данной книги, поэтому при необходимости мы просто будем делать ссылки на некоторые детали. В сети Интернет есть много хороших ресурсов для тех, кто хочет узнать больше об этом веб сервере. Вот некоторые из них, которые нравятся нам самим:
Документация по Apache в свободном онлайн доступе: http://www.djangoproject.com/r/apache/docs/;
Книга Pro Apache, Third Edition (Apress, 2004), автор Peter Wainwright: http://www.djangoproject.com/r/books/pro-apache/;
Книга Apache: The Definitive Guide, Third Edition (O’Reilly, 2002), авторы Ben Laurie и Peter Laurie: http://www.djangoproject.com/r/books/apache-pra/.
Чтобы настроить Django для использования mod_python, сперва необходимо убедиться, что установлен Apache с поддержкой mod_python. Обычно это означает, что в конфигурационном файле Apache присутствует соответствующая директива LoadModule:
LoadModule python_module /usr/lib/apache2/modules/mod_python.so
Теперь добавим в этот файл следующие строки:
<Location "/">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On
</Location>
Вместо mysite.settings необходимо вписать имя модуля настроек Django для вашего сайта.
Такая директива означает, что Apache должен обрабатывать все
URL, начинающиеся от корня сайта, используя обработчик
mod_python от Django. Он передает ему значение переменной
DJANGO_SETTINGS_MODULE
, чтобы mod_python
знал, какие настройки использовать.
Отметим, что мы использовали директиву <Location>, а не <Directory>. Последняя из них указывает на путь в файловой системе, тогда как <Location> используется при формировании структуры URL для вебсайта. Использование <Directory> в таком случае является бессмысленным.
Обычно Apache запускается от имени специального пользователя, которое отличается от вашего логина в систему и имеет другие настройки path и sys.path. Поэтому необходимо указать для mod_python, где искать ваш проект и файлы Django:
PythonPath "['/путь/к/проекту', '/путь/к/django'] + sys.path"
Вы можете добавить дополнительные директивы, такие, как PythonAutoReload Off, для увеличения производительности. Полный список опций можно найти в документации по mod_python.
Рекомендуем отключить опцию PythonDebug (PythonDebug Off) для рабочей версии приложения. Если оставить ее включенной, ваши пользователи увидят некрасивый и избыточный стек ошибок Python, когда возникнут проблемы с mod_python.
Перегрузите Apache и теперь любой запрос к вашему сайту (либо виртуальному хосту, если вы разместили директиву внутри блока <VirtualHost>) будет обрабатываться Django.
Замечание
Если разворачивать Django в подкаталоге, то есть глубже корневого URL, то он не сможет обрезать префикс URL из шаблонов URL. Например, если настройки Apache похожи на эти:
<Location "/mysite/">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On
</Location>
то все шаблоны URL должны начинаться с префикса /mysite/. По этой причине мы обычно рекомендуем разворачивать Django в корень домена или виртуального хоста. Либо, как вариант, можно просто «сдвинуть» все URL вниз на один уровень, используя промежуточный файл со схемой URL:
urlpatterns = patterns('',
(r'^mysite/', include('normal.root.urls')),
)
Запустить несколько проектов Django на одном сервере Apache несложно. Это может понадобится, например, когда у независимого веб разработчика есть несколько клиентов и только один сервер.
Для реализации данного подхода используется блок VirtualHost:
NameVirtualHost *
<VirtualHost *>
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</VirtualHost>
<VirtualHost *>
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
</VirtualHost>
Если необходимо установить два различных проекта в рамках одного и того же виртуального хоста, нужно принять меры, чтобы не допустить смешивания двух различных кэш-копий кода приложений. Используем директиву PythonInterpreter, чтобы указать в каждой директиве <Location> свой обработчик:
<VirtualHost *>
ServerName www.example.com
# ...
<Location "/something">
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
</Location>
<Location "/otherthing">
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter mysite_other
</Location>
</VirtualHost>
Значения параметров для директивы PythonInterpreter можно установить любые, главное, чтобы они отличались между собой для различных блоков <Location>.
Посколько mod_python кэширует загруженный Python код, то при развертывании Django приложений нужно помнить о необходимости рестартовать Apache каждый раз, когда в исходный код внесены изменения. Это быстро может надоесть, поэтому мы предлагаем способ бысто обойти это ограничение: просто добавьте директиву MaxRequestsPerChild 1 в файл конфигурации, чтобы заставить Apache полностью перегружать все при каждом запросе. Только не нужно делать этого на рабочем сервере, иначе мы запретим вам использовать Django.
Если вы относитесь к тем программистам, кто отлаживает код, используя беспорядочно разбросанные операторы print (как мы), учтите, что оператор print не работает в случае использования mod_python и результат его работы не появится в логе Apache, как, возможно, кое-кто ожидал. Для того, чтобы печатать отладочную информацию, рекомендуем использовать стандартный Python модуль logging. Более подробную информацию можно посмотреть тут: http://docs.python.org/lib/module-logging.html. Альтернативным вариантом может быть вывод отладочной информации в шаблонах страниц сайта.
Django не рекомендуется использовать для обслуживания запросов к статическим файлам (контенту); эту работу лучше оставить для веб сервера. Рекомендуется использовать отдельный веб сервер (на котором не работает Django) для обработки запросов к статической информации. Более подробная информация см. ниже в разделе "Масштабирование FIXME".
Однако, если нет других вариантов, кроме работы со статическим контентом на том же сервере Apache, где развернут Django, необходимо отключить mod_python для отдельных частей сайта:
<Location "/media/">
SetHandler None
</Location>
Вместо /media/ необходимо указать корневой URL для статических файлов на вашем сайте.
Можно использовать директиву
<LocationMatch> и работать через
регулярные выражения. Например, вот такая настройка
конфигурации позволяет использовать Django от корня сайта, но
полностью отключает Django для подкаталога
media
, а также для любого URL,
оканчивающегося на .jpg
,
.gif
или .png
:
<Location "/">
SetHandler mod_python
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>
<Location "/media/">
SetHandler None
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler None
</LocationMatch>
Во всех случаях необходимо настроить директиву DocumentRoot, чтобы Apache знал, где ему искать статические файлы.
При использовании Apache/mod_python ошибки перехватываются на уровне Django — другими словами, они не передаются на уровень Apache и поэтому не появляются в логе ошибок Apache.
Исключением тут будет случай, когда что-то серьёзно запорчено при установке Django. Тогда в броузере будет выдаваться страница с ошибкой «Internal Server Error» (код ошибки 500) и полный стек ошибки Python записывается в лог ошибок Apache. Такое сообщение занимает несколько строк. (Да, это выглядит некрасиво и неудобно для изучения, но так работает mod_python).
Иногда Apache падает после установки Django. Если это произошло, то практически всегда это результат одного из двух возможных случаев, не связанных непосредственно с Django:
Возможно, в приложении используется модуль pyexpat (применяется для разбора XML), который может конфликтовать с версией этого же модуля, встроенной непосредственно в Apache. Подробнее см. статью «Expat заставляет Apache сбоить» по адресу http://www.djangoproject.com/r/articles/expat-apache-crash/.
Возможно, в текущей конфигурации одновременно используются mod_python и mod_php на одном и том же сервере Apache, а в качестве базы данных выступает MySQL. В некоторых случаях это может привести к конфликту версий для драйверов MySQL между Python и PHP. Полная информация по данной проблеме доступна в mod_python FAQ по адресу http://www.djangoproject.com/r/articles/php-modpython-faq/.
Если после этого проблемы с mod_python продолжаются, следующим хорошим ходом будет создание «скелета» сайта под mod_python без подлючения библиотек Django. Это самый простой способ изолировать проблемы, специфические именно для mod_python. В статье «Заставляем mod_python работать» эта процедура детально описывается: http://www.djangoproject.com/r/articles/getting-modpython-working/.
На следующем этапе рекомендуем сделать тестовый скрипт и включить в него всё, что вы используете в Django приложении — представления, модели, шаблоны URL, конфигурацию RSS и т.п. Включите этот код в тестовую функцию обработчика и вызывайте тестовый URL. Если это приводит к проблеме, то считаем, что проблема где-то в коде, использующем Django. Комментируя одну за одной строки с import, мы доберемся до конкретного модуля, вызывающего ошибку. Далее то же самое проделываем с кодом модуля, пока не локализуем ошибку. Системные утилиты, такие, как ldconfig в Linux, otool в Mac OS и ListDLLs (от SysInternals) в Windows, помогут найти общие зависимости и возможные конфликты версий.
Пред. | Уровень выше | След. |
Что предпочитают разработчики Django? | Начало | Использование Django с Apache и mod_wsgi |
0 comments | Make a comment