How-to, linux, Maxsite CMS @ 19 Апрель 2009
Общие соображения:
1. VDS которую мне предоставили имеет следующие характеристики ~400Мгц CPU и 256Мб RAM
2. Предварительно я провёл оптимизацию и обновление до Debian 5 выданной VDS.
3. C учётом малого количества оперативной памяти и с учётом моего опыта работы Apache на предыдущей VDS я полностью отказался от него, зато можно выделить куда больше ресурсов для того же mysql.

Итак, начнём со сборки php5 специально для моего проекта. Сборка будет происходить на более мощной машине(2х2Мгц AMD Turion), собираться будет deb пакет, поскольку так не будет лишний раз засоряться система + можно будет добавить свои патчи. Ну и скорость компиляции на локальной машине намного быстрее скорости компиляции на 400Мгц VDS.
Для получения исходников я также использую репозиторий(можно использовать официальный репозиторий, но там версия 5.2.6, но тогда не будет возможности использовать php-fpm патч, поскольку сейчас поддерживается только версия 5.2.8)
deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all

Для того чтобы не было бардака на локальной машине:
mkdir ~/compile && cd compile
Скачиваем исходники:
apt-get source php5
Устанавливаем сборочные зависимости:
sudo apt-get build-dep php5
Сейчас мы будем добавлять возможность php-fpm в сборку пакета php, это не необходимость, и на боевом проекте это делать ненужно(особенно учитывая цель для которой мы это делаем)
cd php5-5.2.9/debian/patches
wget http://php-fpm.anight.org/downloads/head/php-5.2.8-fpm-0.5.10.diff.gz
gunzip php-5.2.8-fpm-0.5.10.diff.gz
echo "php-5.2.8-fpm-0.5.10.diff" >> series

Теперь нужно добавить в debian/rules, в раздел конфигурации пакета php5-cgi, найти его можно по следующей строке configure-cgi-stamp: prepared-stamp
Нужно в эту секцию добавить строки:
--with-fpm-conf=/etc/php5/php-fpm.conf \
--with-fpm-log=/var/log/php-fpm.log \
--with-fpm-pid=/var/run/php-fpm.pid

Следует отметить, что пакет php5-cgi собирается без поддержки баз данных, и дополнительно к нему необходимо ставить пакет php5-mysql, на основе этого можно собирать очень гибкий вебсервер.
Теперь можно обновить changelog пакета
//Имеет смысл в .bashrc добавить свои данные для сборки DEBFULLNAME и DEBEMAIL
export DEBFULLNAME='Nikita A Menkovich';export DEBEMAIL='menkovich@gmail.com';dch -i
И теперь можно начинать сборку пакета(export второй раз делать необязательно):
export DEBFULLNAME='Nikita A Menkovich';export DEBEMAIL='menkovich@gmail.com';debuild -i -us -uc
Следует отметить, что с suhosin patch у меня не собрался пакет, поэтому пришлось удалить патч debian/patches/011* и удалить его из debian/patches/series. Впоследствии его можно будет добавить модулем к php.
Как вариант решения можно предложить удалить его и перед сборкой в директории с исходниками:
wget http://download.suhosin.org/suhosin-patch-5.2.9-0.9.7.patch.gz
gunzip suhosin-patch-5.2.9-0.9.7.patch.gz
patch -p1 < suhosin-patch-5.2.9-0.9.7.patch

И после этого начать сборку.

Теперь приступим к сборке nginx с патчами от catap, я буду использовать нестабильную сборку 0.7.51, поскольку с стабильной версии nginx-0.6.32 которая была в репозиториях debian, произошло относительно много изменений + патчи catap написаны специально под нестабильную ветку nginx(они используются с целью увеличения производительности и снижения потребления памяти)

Переходим в ~/compile
apt-get source nginx
sudo apt-get build-dep nginx
wget http://sysoev.ru/nginx/nginx-0.7.51.tar.gz
cd nginx*

Обновляем и создаём на основе версии из репозитория - новую версию
uupdate --upstream-version 0.7.51 ../nginx-0.7.51.tar.gz
cd ../nginx-0.7.51/

Устанавливаем патчи и выполняем анонимизацию версии nginx(ну и + немного уменьшается объём передаваемых данных, хотя это конечно экономия на спичках)
wget http://catap.ru/downloads/nginx/nginx-catap-0.7.51.389.54fa56f.diff -O catap.patch
patch -p1 < catap.patch

Вырезаем версию и UA вебсервера.
sed -i '/define NGINX_VERSION/s/".*"/"0.0.00"/;/define NGINX_VER\([ \t]*\)"/s/".*"/"nginx\/"/' src/core/nginx.h
sed -i '/SERVER_SOFTWARE/s/nginx\//nginx\//' debian/conf/fastcgi_params

В принципе можно до установки полностью сконфигурировать nginx в директории debian/conf/
Теперь настроим опции конфигурации debian/rules
Добавляем --with-obsd_malloc или --with-jemalloc, --with-http_response_module --with-http_is_bot_module
Подробнее про преимущества других аллокаторов
//Аллокатор - объект который отвечает за распределение памяти
Обновляем changelog
dch -i
И собираем nginx
debuild -i -us -uc

После этого необходимые пакеты из папки compile перенести на вебсервер:
scp nginx* php5* user@host:/home/user/
Логинимся по ssh на user@host
Устанавливаем пакеты: sudo dpkg -i nginx* php5*(выбираете те пакеты что нужны)
Теперь нам нужен будет spawn-fcgi, для того чтобы у нас заработал таки php5
wget http://www.lighttpd.net/download/spawn-fcgi-1.6.2.tar.gz
tar zxvf spawn-fcgi-*.tar.gz
cd spawn-fcgi-*/
./configure --prefix=/usr && make && sudo make install

Теперь нам нужно сделать init скрипт чтобы spawn-fcgi запускал cgi процессы при перезагрузке.
Создаём файл /etc/init.d/spawn-fcgi.sh с следующим содержанием:
#!/bin/sh

USER=www-data
GROUP=www-data
PATH=/sbin:/bin:/usr/sbin:/usr/bin
SCRIPTNAME=/etc/init.d/spawn-fcgi.sh
SSD="/sbin/start-stop-daemon"
PHP_FCGI_CHILDREN=10
PHP_FCGI_MAX_REQUESTS=100000
RETVAL=0

FCGI_DAEMON="/usr/bin/spawn-fcgi"
FCGI_PROGRAM="/usr/bin/php-cgi"
FCGI_PORT="9000"
FCGI_SOCKET="/tmp/php-fastcgi.sock"
FCGI_PIDFILE="/var/run/spawn-fcgi.pid"

test -x $LIGHTY_DAEMON || exit 0

set -e

export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS

. /lib/lsb/init-functions

case "$1" in
start)
log_daemon_msg "Starting spawn-fcgi"
if ! $FCGI_DAEMON -s $FCGI_SOCKET -f $FCGI_PROGRAM -u $USER -g $GROUP -C $PHP_FCGI_CHILDREN -P $FCGI_PIDFILE; then
log_end_msg 1
else
log_end_msg 0
fi
RETVAL=$?
;;
stop)
log_daemon_msg "Killing all spawn-fcgi processes"
if killall --signal 2 php-cgi > /dev/null 2> /dev/null; then
log_end_msg 0
else
log_end_msg 1
fi
RETVAL=$?
;;
restart)
$0 stop
rm $FCGI_PIDFILE
rm $FCGI_SOCKET
$0 start

;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
exit 1
;;
esac


Делаем его исполняемым:
sudo chmod +x /etc/init.d/spawn-fcgi.sh
И добавляем его в загрузку
sudo update-rc.d spawn-fcgi.sh defaults
и стартуем его
sudo /etc/init.d/spawn-fcgi.sh start
и смотрим действительно ли php-cgi слушает нужный нам порт
netstat -nlp
//я чуть позже сделаю пакет для всего этого, сейчас не очень много времени для этого
Теперь приступим к конфигурации nginx:
Нужно в /etc/nginx/sites-enabled/default
раскомментировать:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}

Следует обратить внимание, что include fastcgi_params; было написано слитно
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
/scripts нужно заменить на ваш document_root, например /var/www
Дополнительно можно почитать про настройку nginx здесь. Там приведён достаточно интересный конфиг nginx и впринципе весьма интересные мысли по оптимизации вебсервера.

Теперь установим свежую версию eaccelerator, популярного opcode кэшера.
Добавим два репозитория где этот пакет есть:
deb http://debian.mcmillan.net.nz/debian lenny awm
deb-src http://debian.mcmillan.net.nz/debian lenny awm

Импортируем ключи в apt
gpg --keyserver pgp.mit.edu --recv-keys 8C90347F8F068012
gpg --export 8C90347F8F068012 | sudo apt-key add -
sudo apt-get --build source php5-eacclerator

После этого начнётся его сборка под ту версию php что Вы используете.
После окончания - устанавливаем:
sudo dpkg -i php5-eaccelerator*deb

Первичные тесты производились на странице с исполняемым кодом phpinfo
Requests per second: 70.56
Второй тестовый скрипт, который участвовал в тестировании - скрипт подсчёта от 0 до 10000.
Requests per second: 22.88

Третий тест будет производится на реальной CMS на базе фреймворка Codeigniter, с улучшенным кешированием и поддержкой opcode кэшера eAceelerator. Естественно CMS будет работать с базой данных. Не так активно, как большинство CMS(изза продвинутого кэширования запросов)
Наиболее оптимальным конфигом баз данных я могу назвать примерно следующий, следует учесть, что конфигурация сервера баз данных не производилась с особым тщанием, не было включено кэширование mysql запросов со стороны сервера, также можно увеличить ресурсы оперативной памяти выделяемой mysql серверу, поскольку при использовании сверхэкономичной связки nginx+php-fcgi можно отдать на откуп mysql намного больше оперативной памяти.
На текущий момент было создано 7 child-ов php-cgi процесса, поскольку большее количество просто не используется, а меньшее уже даёт достаточно сильную просадку по производительности.
Текущая производительность находится на отметке:
Requests per second: 34.71
Что не сильно меньше, чем отдача практически статической страницы phpinfo(), чистая статика безусловно отдаётся с намного большей скоростью ~100-200 запросов в секунду.

Что хочу сказать - я пока не затрагивал настройку mysql, однако я считаю что вполне достаточно будет использовать конфигурацию medium
zcat /usr/share/doc/mysql-server-5.1/examples/my-medium.cnf.gz > /etc/mysql/my.cnf

4 Response to “Установка связки nginx->spawn-fcgi на VDS от SpaceWeb”

  1. Fd Says:

    а как насчёт авторских прав и лицензии в районе вырезания сигнатуры веб-сервера? лицензия всё же BSD-like.

  2. librarian Says:

    Сигнатура вообще то осталась, UA вебсервера есть - nginx. Я вырезал лишь версию вебсервера.

  3. catap (анонимно) Says:

    Говорю как автор этого большого патча. Лучше ссылку давать сюда: http://catap.ru/nginx-catap/

    Там я стараюсь описывать все что сделал. Иногда даже зачем ;)

  4. killaherz (анонимно) Says:

    Что только не придумают, лишь бы lighttpd не использовать...

Leave a Reply

Не регистрировать/аноним

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email.
(При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д.)


(обязательно)