Блог Синявского
  • Разделы
  • Метки
  • Все статьи

Django lighttpd fastcgi +spawning

1

Lighttpd - это гиперзвуковой реактивный истребитель среди веб-серверов по скорости работы, по скорости отдачи статики. После непродолжтительного времени использования lighttpd в своих проектах, я проникся "философией" этого сервера. Скажу, что мне очень понравились принципы его конфигурирования. Раньше я пользовался исключительно nginx и буду использовать в больших коммерческих проектах, но теперь очень пристально изучаю возможность использования lighttpd и в них.

Особенности lighttpd

Достоинства:

  1. Нет виртуальных хостов в понимании Apache или nginx. Здесь только один сервер и ты должен ему объяснить как обрабатывать HTTP запросы и заголовки на определенном порту. Возможности конфигурирования теже самые, но подход выглядит более гибким. В связи с этим error лог один на весь сервер, а access логи можно создавать для каждой секции в отдельности url, host, socket.

  2. Любит заранее подготовиться к большой нагрузке. Жмет статику и складывает ее в определенную папку на сервере. В следующий раз обращается к ней. Можно эту папку сделать ramdisk например.

  3. spawning - при использовании mod_fastcgi управляет дочерним(и) процессом(и), количеством дочерних процессов.

Недостатки:

  1. Некоторые моменты не настолько очевидны, как в nginx, и требуют костыльных решений. Например, нельзя сделать rewrite-once c проксированием на другой сервер, если до этого был сделан rewrite-once в определенный url. Т.е. запрос вида someserver1.com:80/sometext/someurl => someserver2.com:80/someurl (в принципе, все понятно и в версии 1.5 есть все необходимые инструменты для этого). Об этом можно прочитать здесь.

  2. Сложные и длиннные файлы конфигурации становятся не читабельны. После nginx, смотришь на большой конф, как после Python кода - на код PHP.

Лично для меня достоинства очень сильно превалируют над недостатками. Хотя бы даже только по причине автоматического spawning.

Рассуждения на тему spawning

Для меня самой важной особенностью является spawning. Обычно когда мы пишем веб-приложение на Python, с использованием Django, flask или просто flup, то приходится думать, как контролировать backend. При использовании nginx например, nginx будет принимать запросы, а backend может в любой момент "отвалиться". Иными словами помимо дополнительных безумных (shell, bash) скриптов запуска (остановки, перезагрузки) в /etc/init.d/ для backend, его еще нужно контролировать. А перезапуск сервера при большом количестве проектов вообще может стать головной болью администратора. Что-то обязательно не запустится.

Сконфигурируем python веб-приложение на основе Django

Установим веб-сервер lighttpd:

$ sudo su
# apt-get install lighttpd

Важно! Я писал о том, как я располагаю файлы проектов на сервере (первый раз и второй). Напомню, что везде в листингах <project_name> имя проекта.

Создадим файл конфигурации в каталоге /etc/lighttpd/conf-available/ (название должно иметь расширение .conf) и символическую ссылку на него в каталоге /etc/lighttpd/conf-enabled/:

# cd /etc/lighttpd
# touch conf-available/<project_name>.conf
# ln -s ../conf-available/<project_name>.conf conf-enabled/

Перейдем к редактированию:

nano /etc/lighttpd/conf-available/<project_name>.conf
# подключаем необходимые модули,
# если они не подключены в главном файле конфигурации /etc/lighttpd/lighttpd.conf
server.modules += ("mod_fastcgi")

# создадим секцию "виртуального хоста"
$HTTP["host"] =~ "^(.+\.)?(somedomain\.com)" {
    accesslog.filename = "/web/<project_name>/logs/access.log"

    $SERVER["socket"] == ":80" {
        # любое название, главное чтобы такой url больше не встречался в проекте
        # я использую random key (aFn2HBWNEFj2QvJCrwcIU) для того,
        # чтобы сложно было обратиться по этому локейшену напрямую слэш обязателен
        fastcgi.server = ("/aFn2HBWNEFj2QvJCrwcIU.fcgi" =>
                    ( "" => (
                        "socket" => "/web/<project_name>/run/django.sock",
                        "check-local" => "disable",
                        "min-procs" => 1,
                        "max-procs" => 4,
                        "bin-path" => "/web/<project_name>/env/bin/python /web/<project_name>/project/manage.py runfcgi method=prefork"
                    )
                )
            )

        # путь к django статике
        alias.url = ( "/static_serve/" => "/web/<project_name>/project/static_serve/" )


        # приоритет выполнения у rewrite-once наивысший, выполняется один раз
        # чтобы все не переадресовывалось на fastcgi нужно прописывать
        # другие locations
        # первый встретившийся по списку сразу обрабатывается

        url.rewrite-once = (
            "^/favicon.ico$" => "/static_serve/img/favicon.ico",
            "^/static_serve/(.*)$" => "/static_serve/$1",
            "^/(.*)$" => "/aFn2HBWNEFj2QvJCrwcIU.fcgi/$1"
        )
    }
}

Хочу обратить внимание на строку запуска дочернего процесса /web/<project_name>/env/bin/python /web/<project_name>/project/manage.py runfcgi method=prefork. Здесь обязательно должен быть указан method=prefork, в этом случае сокет для связи родителя и процесса передается автоматически. Не нужно его указывать в строке запуска.

Перезагружаем сервер правильно

# lighttpd -t -f lighttpd.conf
Syntax OK
# service ligthtpd restart

Исправляем urls

Для того, чтобы urls были нормального вида somedomain.com/admin/, а не somedomain.com/aFn2HBWNEFj2QvJCrwcIU.fcgi/admin/, в Django settings.py (или local_settings.py) добавляем FORCE_SCRIPT_NAME = ''. Так будет работать.

Apache, Nginx??? ...Нет, нет, не надо. Lighttpd!

Если статья была вам полезна просьба щелкнуть по рекламе. Спасибо!



  • ← сюда
  • туда →

comments powered by Disqus

Опубликовано

01.10.2014

Обновление

05.05.2022

Категории

django

Тэги

  • django 12
  • lighttpd 7

Всегда на связи

  • Блог Синявского - Ничего не переносить на завтра, это тоже проблема с прокастинацией?
  • © Алексей Синявский, по лицензии CC BY-SA если не указано иное.
  • С использованием Pelican. Тема: Elegant от Talha Mansoor