Установка и настройка Django на «боевом» сервере с CentOS 5

    Я делаю на Django Энциклопедию языков программирования, о которой уже писал на Хабре. За время работы сайта выяснилось, что нужен свой выделенный сервер для большей производительности и стабильности. Пока что взял дешевый сервер с 1.8 ГГц процессором и 512 Мб памяти.

    В этой статье я расскажу об установке и настройке на этом сервере Django с mod_python для Apache, с кэшированием memcached и lighttpd для статических файлов.


    Итак, у нас есть свежеустановленная CentOS 5 и желание хостить сайт на Django (или несколько сайтов).

    Что для этого надо установить?

    1. Собственно Django
    2. MySQL-python
    3. mod_python
    4. memcached
    5. lighttpd


    Все шаги, кроме установки самого Django, — необязательные (например, можно использовать Django с fcgi вместо mod_python и PostgreSQL или другую СУБД вместо MySQL), но шаги 1-3 – то, что вы скорее всего будете использовать, а 4-5 – для повышения производительности.

    Статья, в основном, CentOS-ориентированная, но в определенной степени подойдет и для других дистрибутивов Linux.

    Замечание по безопасности: так как это свежеустановленная система, я не боюсь сломать что-то уже работающее, так что могу работать под правами root. Но лучше, конечно, работать под правами непривилегированного пользователя, и использовать “sudo” для команд, требующих административные привилегии.

    Ну, начнем.

    Собственно Django

    В большинстве случаев стоит устанавливать самую свежую svn-версию Django, а не “релиз”. На сегодняшний момент, “официальный релиз” слишком устарел, и в нем отсутствует множество полезных возможностей (например, поддержка unicode и auto-escape).

    Для установки вводим в командной строке
    svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
    
    Но сначала нужно установить svn
    yum install subversion
    
    После получения всех файлов с svn нужно сделать символическую ссылку на Django в директории site-packages для Python :
    ln -s `pwd`/django-trunk/django /usr/lib/python2.4/site-packages/django
    
    Убедитесь, что у всех родительских директорий каталога django установлены верные права (доступ на чтение для пользователя httpd, обычно chmod 755).

    Также установка Django с svn рассмотрена в официальной документации Django.

    После установки Django нужно скопировать на сервер файлы вашего проекта (через svn или просто копированием по ssh или ftp; также стоит завести в системе отдельного пользователя, который будет владельцем этих файлов) и дамп базы данных, а потом подкорректировать связанные с БД настройки в файле settings.py (подразумевается, что MySQL уже установлен и настроен, база данных и пользователь созданы, все данные на месте – эти вещи далеко за рамками этой статьи).

    Теперь попробуйте запустить Django development-сервер из директории проекта
    python manage.py runserver 127.0.0.1:8000
    
    На CentOS 5 будет сообщение об ошибке “Error loading MySQLdb module”.

    Версия MySQL-python в дистрибутиве CentOS слишком старая для запуска свежей svn-версии Django, так что нужно собирать из исходников.

    MySQL-python

    cd /usr/local/src
    wget http://garr.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.2.tar.gz
    tar xvzf MySQL-python-1.2.2.tar.gz
    cd MySQL-python-1.2.2
    


    Для сборки MySQL-python понадобятся пакеты gcc, python-devel и mysql-devel.
    yum install gcc
    yum install python-devel
    yum install mysql-devel
    
    cd /usr/local/src/MySQL-python-1.2.2
    python setup.py build
    python setup.py install
    
    Готово, MySQL-python установлен как .egg-файл в директории site-packages.

    Снова попробуйте запустить python manage.py runserver 127.0.0.1:8000 и проверьте, нет ли каких ошибок. Например, я использую ImageField в своем проекте, так что мне нужно было дополнительно установить Python Imaging Library (yum install python-imaging).

    Если ошибок нет, стоит сменить 127.0.0.1 в команде runserver на IP-адрес вашего сервера и проверить работу сайта при помощи браузера, но для этого нужно в брандмауэре CentOS открыть порт 8000 или временно выключить брандмауэр (или можно просто временно выключить Apache и запустить Django development-сервер на 80-том порту).

    Если ошибок нет, то самое время выключить Django development-сервер и настроить Apache.

    mod_python

    Настроить Apache с mod_python на работу с Django просто: достаточно следовать инструкциям из официальной документации Django.

    Одно замечание: так как MySQL-python установлен в виде egg-пакета, важно создать временную директорию (установите на нее права 777) для кэширования .egg и указать на нее в httpd.conf

    <Location "/">
        ...
        SetEnv PYTHON_EGG_CACHE /var/tmp/egg
    </Location>
    
    И не забудьте перезапустить Apache после изменения httpd.conf:

    /etc/init.d/httpd restart
    
    Сейчас сайт должен работать через Apache на обычном http-порту. Проверьте браузером.


    memcached

    Включение кэширования memcached очень важно для увеличения производительности. К сожалению, memcached отсутствует в репозитариях CentOS, так что опять придется собирать из исходников. Этот раздел статьи частично основан на этом HOWTO.

    Сначала нужно установить libevent:

    cd /usr/local/src
    wget http://monkey.org/~provos/libevent-1.4.2-rc.tar.gz 
    tar xvzf  libevent-1.4.2-rc.tar.gz
    cd libevent-1.4.2-rc
    ./configure
    make
    make install
    
    vi /etc/ld.so.conf.d/libevent.conf
    ## добавьте строку:
    /usr/local/lib/
    
    ldconfig -v
    
    Затем собственно memcached:

    cd /usr/local/src
    wget http://danga.com/memcached/dist/memcached-1.2.5.tar.gz
    tar zxvf memcached-1.2.5.tar.gz
    cd memcached-1.2.5
    ./configure
    make
    make install
    
    cp scripts/memcached.sysv /etc/init.d/memcached
    
    ln /usr/local/bin/memcached /usr/bin/memcached
    /etc/init.d/memcached start
    
    chkconfig memcached on
    
    И наконец нужно установить libmemcache и cmemcache (python-расширение для libmemcache):

    cd /usr/local/src/
    wget http://people.freebsd.org/~seanc/libmemcache/libmemcache-1.4.0.rc2.tar.bz2
    bunzip2 libmemcache-1.4.0.rc2.tar.bz2
    tar xf libmemcache-1.4.0.rc2.tar
    cd libmemcache-1.4.0.rc2
    ./configure
    make 
    make install
    
    cd /usr/local/src/
    wget http://gijsbert.org/downloads/cmemcache/cmemcache-0.91.tar.bz2
    bunzip2 cmemcache-0.91.tar.bz2
    tar xf cmemcache-0.91.tar
    cd cmemcache-0.91
    python setup.py install
    
    
    Включите memcached-кэширование в settings.py своего проекта

    CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
    
    (если нужно больше информации, посмотрите в официальной документации Django) и перезапустите Apache.

    Чтобы получить еще большую производительность, нужно статические файлы отдавать не при помощи Apache, а менее ресурсоемким сервером – lighhtpd.

    lighttpd

    Опять-таки, устанавливаем из исходников.
    cd /usr/local/src
    wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.bz2
    bunzip2 lighttpd-1.4.19.tar.bz2
    tar xf lighttpd-1.4.19.tar
    cd lighttpd-1.4.19
    yum install glib2-devel openssl-devel pcre-devel bzip2-devel gzip-devel
    ./configure
    make 
    make install
    
    cp doc/rc.lighttpd.redhat /etc/init.d/lighttpd
    chkconfig lighttpd on
    
    mkdir /etc/lighttpd
    cp doc/lighttpd.conf /etc/lighttpd/
    
    А теперь нужно настроить Apache и lighttpd, чтобы статические файлы отдавались lighttpd (на 80 порту), а остальные запросы обслуживал Apache на 81 порту (спасибо nolancaudill.com за это решение):

    • Настройте Apache на 81 порт: найдите
      Listen 80 и замените на Listen 127.0.0.1:81. Также не забудьте сменить номер порта во всех VirtualHost-директивах. Перезапустите Apache.
    • Отредактируйте /etc/lighttpd/lighttpd.conf. Снимите комментарии с модулей ‘mod_alias’ и ‘mod_proxy’ и добавьте строки (подкорректируйте под свои нужды):

      $HTTP["host"] == "yourdomain.com" {
      
          # here we are mapping /media/ for admin media
          # and /static/ for the standard media_url
          alias.url = (
             "/media/" => "/usr/lib/python2.4/site-packages/django/contrib/admin/media/",
             "/static/" => "/var/www/html/media.yourdomain.com/",
          )
      
      
          $HTTP["url"] !~ "^/(static|media)/" {
              proxy.server = ( "" => (("host" => "127.0.0.1", "port" => 81 )) )
      
          }
      
      }
      
      


    Также смените server.document-root на “/var/www/html/” и создайте символическую ссылку “/var/www/html/media.yourdomain.com/”, указывающую на media-директорию вашего проекта.

    • Cоздайте директорию для лог-файлов lighttpd:

      mkdir /var/log/lighttpd/
      

    • Еще одна маленькая правка в /etc/init.d/lighttpd: смените пусть с /usr/sbin/lighttpd на /usr/local/sbin/lighttpd. Запустите lighttpd:

      /etc/init.d/lighttpd start
      


    И в конце еще несколько советов по производительности:
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 14

      0
      Черезвычайно интересно.
      Кроме того интересно, какую нагрузку способен выдерживать сервер подобной конфигурации под Django. Цифр, добавьте цифр.
        0
        А как тестировать? Если б был готовая методика тестирования, я бы провел тесты, например, без memcached, без lighttpd и т.д.
        Но, насколько я понял, очень непросто сделать обобщенный тест. А тестировать просто свое конкретное приложение не хочется - смысла нет особого.
          +1
          Для тестирования используют несколько приложений:
          Siege
          Http_load
          ab

          Что бы не изобретать велосипед, Zada, рекомендую ознакомиться с результатами тестирования http://www.alrond.com/ru/2007/jan/25/rez…
          Там же описывается методика тестирования.
            0
            Про ab понятно. Вопрос именно в проекте для тестирования.
            Проект http://static.alrond.com/source_dj.txt имеет мало общего с реальными проектами.
            Hello World-ы не очень-то интересно тестировать.
            К тому же, пользы от кэширования, например, на Hello World-е видно не будет.
            0
            Я не про тестирование, как таковое, а как вообще ведет себя сервер подобной конфигурции (слабоват по современным меркам), на что способен, не задыхается ли. Вот про что. А про бенчмарки обобщенные и так написано много.
          0
          Советую посмотреть в сторону nginx для отдачи статики.
            0
            Пока поставил то, что советуют в официальной документации.
            В будущем попробую nginx.
            0
            > Пока что взял дешевый сервер с 1.8 МГц процессором и 512 Мб памяти.
            Наверное, 1.8 ГГц?
              +1
              Точно, спасибо :-D
              0
              Я ставил свой проект на Django на RedHat. Делал сразу на nginx таким образом: процесс джанги запускается
                $ manage.py runfcgi method=threaded daemonize=true socket=/var/run/dj.sock
              в настройке nginx указывал, что определенные урлы (скажем /back_office ) проксировались по FastCGI в этот сокет, все остальное (картинки, цсс, скрипты) отдавалось сразу nginx-ом.
                0
                Я поставил nginx + fastcgi. Статику отдаю так же nginx'ом. В итоге имеем 1 быстрый веб-сервер вместо 2-х. Вообще с трудом представляю, зачем для Django тяжеловесный Apache. Никаких особых возможностей апача джанго не требуется.
                  +1
                  Апач позволяет сделать запуск Django по требованию. Если, скажем, есть несколько не сильно посещаемых сайтов, то это позволит сэкономить память.
                  0
                  После установки memcached перед его запуском следует создать директорию /var/run/memcached.
                    0
                    Также в случае исключительно локального применения memcached полезным окажется отредактировать параметры запуска (в файле /etc/init.d/memcached) так, чтобы прослушивался только loopback-интерфейс:
                    daemon memcached -d -p $PORT -l 127.0.0.1 -u $USER -m $CACHESIZE -c $MAXCONN -P /var/run/memcached/memcached.pid $OPTIONS

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

                    Самое читаемое