You are here

Drupal 7 върху Debian 6 Squeeze + Apache + PostgreSQL

Въведение

Бързината на сайта има голямо значение за сърфистите. Даже и да е много удобен като интерфейс или дизайн, бавният сайт отблъсква.

Тук ще разгледаме начин за инсталиране на Drupal със следните изисквания:

  • ще се използва от няколко сайта едновременно (многосайтов Drupal)
  • върху VPS (Virtual Private Server – виртуален частен сървър) със сравнително ограничена памет
  • операционната система е Debian 6 Squeeze
  • уеб сървърът е Apache
  • базата данни е PostgreSQL

Защо Debian?

Основният съперник на Debian в областта на сървърските инсталации е CentOS, която се управлява от фирмените нужди на Red Hat. Теоретично Debian изцяло се управлява от нуждите на своите Debian Developers и аз съм един от тях. Затова Debian :-)

Защо Apache?

Модата сега е вместо Apache да се използва nginx. Все пак Apache продължава да е най-популярният сървър и натрупаното знание за него си тежи. Лошата му слава до голяма степен се дължи на стария модел mpm_prefork, при който обработката на всяка заявка изисква отделен процес. Всеки процес има копие на всички модули, включително и този на PHP, без значение дали това е статичен файл или скрипт на PHP. Тази стара технология на обработка на заявки отдавна има алтернатива mpm_worker, където всяка заявка е в отделна нишка на процес, а това е много по-леко (и съответно бързо) по отношение на процесорни и паметови ресурси. PHP обаче не е преправено за този модел на работа и трябва да се използва CGI, което създава процес за всяка заявка. Това е много по-бавно от mpm_prefork. Решението е използването на FastCGI, където един процес може да обработва много последователни заявки. Разбира се, могат да се пускат няколко такива процеса и те едновременно да обработват заявки. Статичните файлове се поемат от уеб сървъра. Това не е популярно в статиите за Apache, но често се използва в nginx. Само тази промяна до използване на комбинацията mod_worker + PHP-FastCGI значително скъсява разликата между Apache до nginx по отношение на използваната памет. За пълноценно използване на FastCGI обаче е нужен PHP-FPM, който не е пакетиран в Debian 6 Squeeze. Това е новият код на проекта PHP за FastCGI, с много подобрено управление на много процеси, които обработват заявки. С Apache както е в Debian 6 Squeeze не можем да използваме даже старото управление на процеси на PHP FastCGI и оставяме това управление изцяло в ръцете на mod_fcgid. Значението на това се проявява когато искаме да използваме ускорителя PHP APC, при който хилядите редове на Drupal само веднъж се прочитат и се съхраняват като „опкод“ (байткод) в кеша на APC. Когато се използва PHP като модул, този кеш е общ за всички процеси в Apache, но когато се използва mod_fcgid, всеки процес е с отделен кеш, т.е. трябва да се строи наново при създаване на нов процес за FastCGI, което освен време, хаби и памет. Тази ситуация се решава с PHP-FPM, но той не е официално пакетиран за Debian 6 Squeeze, затова не се разглежда тук.

Освен mpm_worker има и още един модел – mpm_event, който се справя с проблема с чакащите заявки (keep alive). Той обикновено се счита за експериментален, но това просто не е вярно. Много си е стабилен и затова го използваме в тази статия.

Друг недостатък на Apache спрямо nginx е недоразвитостта на кеширането му на резултати, т.е. действането като кеширащо обратно прокси.

Въпреки тези недостатъци, Apache не е чак толкова зле, ако се подходи грамотно. На мен ми харесва модулността му и организацията на кода/API-то.

Защо PostgreSQL?

Обикновено се използва MySQL, който се справя бързо с малки натоварвания и просто заявки. PostgreSQL обаче смятам за много по-надежден при големи натоварвания и тежки ситуации. Това далеч надхвърля наличието на транзакции. PostgreSQL се прави от малка група хора, чиято цел е развиването на най-напредничавата релационна БД с отворен код.

Инсталиране на Apache

Започваме с най-видимата част от инсталацията.

# aptitude install apache2-mpm-event libapache2-mod-fcgid

Няма да използвама CGI и едва ли ще ви се наложи да използвате mod_negotiation.

# a2dismod cgid negotiation

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

# a2dismod status auth_basic authz_default authz_user authz_groupfile authn_file

Следните модули не са нужни на самия Drupal, но обикновено администраторите очакват да са активирани.

# a2dismod alias autoindex env setenvif

Ето какво би трябвало да е останало в /etc/apache2/mods-enabled: authz_host deflate dir headers mime reqtimeout rewrite.

Активираме mod_fcgid, а също някои модули, които се използват от .htaccess на Drupal.

# a2enmod fcgid rewrite expires

Настройваме да се използва PHP FastCGI. В тази директория пакети могат да слагат свои настройки, затова ръчно създадените файлове са с наставка .local. По подразбиране php5-cgi прекратява своята работа след 500 обработени заявки, което обаче обърква mod_fcgid и се връща грешка 500 Internal Server Error,  а следващите заявки създават нов процес и всичко продължава нормално още 500 заявки. За избягване на това инструктираме mod_fcgid да не използва повече от 499 заявки към един процес php5-cgi. По подразбиране mod_fcgid може да пусне едновременно 100 FastCGI процеса, но ние се целим в случай с ограничена памет и затова трябва да се ограничи по някакъв начин. Числото 10 тук е напълно произволно. Ресурсите основно се харчат от PHP и ще трябва да се преценява конкретната ситуация и конкретната налична памет.

# cat > /etc/apache2/conf.d/php5.local << EOF
AddHandler fcgid-script .php
FcgidWrapper /usr/bin/php5-cgi
FcgidCmdOptions /usr/bin/php5-cgi \
  MaxRequestsPerProcess 499 \
  MaxProcesses 10
EOF
# /etc/init.d/apache2 reload

Инсталиране на PHP

Инсталираме PHP, APC и Memcached. apc.rfc1867 се използва за индикатор по време на качване, но в Drupal 7.0 този индикатор е развален. apc.shm_size стандартно е 30 и това е достатъчно, ако не се използва за кеш за данни, но модулът за статистика на производителността си настоява за 48. PHP в Debian 6 Squeeze по подразбиране е с ограничение 128M и това би трябвало да е достатъчно. За качване на по-големи файлове трябва да се променят 3 настройки, като post_max_size е максимална големина на цял формуляр, който може да включва и файлове, затова трябва да е малко по-голямо. По подразбиране memcached съхранява до 64M, ако е нужна промяна, се увеличава в /etc/memcached.conf.

# aptitude install php5-cgi php5-gd php5-pgsql php-apc php5-memcached memcached
# cat > /etc/php5/conf.d/local-drupal.ini << EOF
apc.rfc1867 = On

;memory_limit = 128M
apc.shm_size = 48

apc.max_file_size = 10M
upload_max_filesize = 10M
post_max_size = 12M
EOF

Инсталиране на PostgreSQL

Нищо необичайно тук. Подразбиращите се параметри на създавания потребител и база данни са точно каквито ни трябват.

# aptitude install postgresql
# su - postgresql
$ psql
postgres=# CREATE USER drupal PASSWORD '<password>';
CREATE ROLE
postgres=# CREATE DATABASE drupal OWNER drupal;
CREATE DATABASE
postgres=# <Ctrl-D>
$ <Ctrl-D>

Ако е нужна настройка на PostgreSQL, има няколко параметъра, който влияят драматично: Tuning Your PostgreSQL Server. Не забравяйте, че Debian 6 Squeeze използва версия 8.4 и че тези настройки се намират в /etc/postgresql/8.4/main/postgresql.conf.

shmmax

Параметърите apc.shm_size на PHP APC и shared_buffers на PostgreSQL са ограничени от параметъра на ядрото kernel.shmmax, който в Debian 6 Squeeze е с твърде ниска стойност, около 30M. Ето лесна команда, с която текущата стойност се умножава по десет, запазва се като настройка за следващи рестартирания и веднага влиза в употреба.

# sysctl kernel.shmmax | sed s/$/0/ > /etc/sysctl.d/local-shmmax.conf
# /etc/init.d/procps restart

/srv

Искаме да използваме един Drupal, който да се използва от много сайтове. Това е вградено в Drupal чрез отделни директории sites/example.com, където са settings.php и публичните файлове. Често обаче са нужни и още неща, който не искаме да са в това дърво, като например журнала на достъпа до сайта. Това може да се ограничи с ограничаване на достъпа, но тук ще използваме по-различно решение. Всеки сайт пази нещата си в /srv/example.com, а общият Drupal е в /srv/drupal.

Една от новостите в Drupal 7 е възможността през уеб интерфейс да се инсталират и обновяват модули, като се използва FTP или SSH за самата промяна на файловата система. Има обаче и трети вариант, при който Drupal направо променя файловата система, но за това е нужно потребителят на уеб сървъра да е собственик на определни директории. Долните команди осигуряват нужните права.

# cd /srv
# mkdir -p example.com/{log,site}
# chown www-data: example.com/site
# wget http://ftp.drupal.org/files/projects/drupal-7.0.tar.gz
# tar xzf drupal-7.0.tar.gz
# mv drupal-7.0 drupal
# cd drupal
# chown -R root: .
# chown -R www-data: sites/all
# cd sites/default
# cp default.settings.php settings.php
# chown www-data: . settings.php

Виртуален хост

В Debian конвенцията е всеки виртуален хост да е в отделен файл. Следват минималните настройки за Drupal, деактивиране на стандартния виртуален хост и активиране на новия:

# cat > /etc/apache2/sites-available/example.com << EOF
<VirtualHost *:80>

  ServerName example.com
  ServerAlias www.example.com
  ServerAdmin webmaster@example.com

  DocumentRoot /srv/drupal
  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>
  <Directory /srv/drupal>
    Options FollowSymLinks ExecCGI
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>

  ErrorLog /srv/example.com/log/error.log
  LogLevel warn
  CustomLog /srv/example.com/log/access.log combined

</VirtualHost>
EOF
# a2dissite default
# a2ensite example.com
# /etc/init.d/apache2 reload

Инсталиране

Ако за това са ви нужни инструкции, значи този документ не е за вас :-)

Трябва да сте наясно с всяка настройка в Configuration. За нашите цели е особено важно да се сложат отметки навсякъде в Configuration - Development - Performance.

Инсталира се модула memcache, но не трябва да се активира! Той се използва във файла с настройки както е показано по-долу. Удобно е да се инсталира през уеб интерфейса, има препратка в страницата със списъка с модули. Ако всичко по правата на директориите е както трябва, няма да се пита за прехвърляне на модула по FTP (или SSH, но за SSH се изисква модул и на PHP).

Окончателно настройване и прехвърляне в /srv

Трябва да се преместят новосъздадените настройки на окончателното си място. Добавят се настройки за (1) използване на memcache (много е важно), (1) за бързо сервиране (без участието на PostgreSQL, само memcache) на страници за анонимни потребители и (3) за позволяване на обратни проксита да кешират страници. За последното се налага да заковем времената още тук, понеже тази настройка е нужна при сервиране на кеширана страница, а в тази ситуация сме указали да няма PostgreSQL, където Configuration - Development - Performance ги съхранява. Тези 3 настройки са целия повод да се напише тази статия :-)

В тези примерни добавки е добавено и коментирано използване на кеша на APC за две ключови кеширащи таблици. При използване на mod_fcgid обаче биха се получили опасни разминавания между кешовете и затова в този случай не трябва да се разкоментира. (Когато трябва да се изчистят всички кешове по някаква причина, те ще се изчистят само в текущия PHP FastCGI процес, а в другите процеси ще има стари стойности.)

Забележете, че от модула memcache просто се използва файла, а няма никакво значение дали е активиран. Същото е за apc.

# cd /srv/drupal/sites/default
# chown root: settings.php
# cat >> settings.php << EOF
$conf['cache_backends'] = array(
//  'sites/all/modules/apc/drupal_apc_cache.inc',
  'sites/all/modules/memcache/memcache.inc',
);
//$conf['cache_class_cache'] = 'DrupalAPCCache';
//$conf['cache_class_cache_bootstrap'] = 'DrupalAPCCache';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['memcache_key_prefix'] = 'example.com';

$conf['page_cache_without_database'] = TRUE;
$conf['page_cache_invoke_hooks'] = FALSE;
$conf['page_cache_maximum_age'] = 300;
$conf['cache_lifetime'] = 900;
EOF
# mv files settings.php /srv/example.com/site
# cd ..
# ln -s /srv/example.com/site example.com

Ако сайтът има различни имена, те трябва да са описани в /srv/drupal/sites/sites.php. За целта трябва да се прочетат коментарите в settings.php и examples.sites.php.

Следене на паметта

Следната команда е удобна за следене на статуса на демоните в сървъра. Може да се направи като скрипт. PID ни трябва за команди като strace, lsof, kill. NLWP е броят нишки в процеса. %CPU и %MEM показват какъв процент от съответния ресурс заема процеса. RSS е колко физическа памет ангажира в момента процеса. SIZE е предположение колко памет би отнел процеса в суапа, ако трябва изцяло да се прехвърли там. VSZ е обема на виртуалната памет.

# ps axf -o pid,nlwp,%cpu,%mem,rss,size,vsz,comm | egrep 'PID|apache|php|memcache|postgres'

Apache 2.4

Най-добрият вариант за PHP в момента е PHP-FPM и Apache 2.4 ще може да го използва ефективно с новия модул mod_proxy_fcgi.

За съжаление кеширането в Apache 2.4 все още не е оправено, но има време и това да се случи.

Обратна връзка

Все още не съм измислил анти-спам защитата за коментари и затова ако искате да коментирате нещо, ще трябва да ми пишете на ogi@tower.3.bg.

Tags: 

User login