Хостинг Django от «Джино»
Table of contents

Использование Django с Apache и mod_python

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 выходит далеко за рамки данной книги, поэтому при необходимости мы просто будем делать ссылки на некоторые детали. В сети Интернет есть много хороших ресурсов для тех, кто хочет узнать больше об этом веб сервере. Вот некоторые из них, которые нравятся нам самим:

Базовые настройки

Чтобы настроить 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

Запустить несколько проектов 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

Посколько 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 и статическим контентом на одном сервере Apache

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

Иногда 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, помогут найти общие зависимости и возможные конфликты версий.


Ищем Python программистов

Found misprint?
Select it with the mouse and hit Enter
Ctrl-Enter
Processed:
33 1 199 25


The full repository of DjangoBook translation you can get on GitHub.
We appreciate your patches!

We are glad to hear your questions, comments or suggestions!
(Open in new tab)

Users number: 601

Русская группа

на поддержку перевода
Яндекс Яндекс.Деньги Хочу такую же кнопку
Ускорить процесс перевода!
ЯМ:41001223475816


© 2008-2012 Ruslan Popov @ gmail.com Powered by Django 1.2.5