Въведение
Бързината на сайта има голямо значение за сърфистите. Даже и да е много удобен като интерфейс или дизайн, бавният сайт отблъсква.
Тук ще разгледаме начин за инсталиране на 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.
- Log in to post comments