Настройка spawn-fcgi в Arch Linux

В недавнем прошлом столкнулся с проблемой — раз или два в день на сервере отваливалась обработка скриптов бекендом (php-cgi). Уловить закономерность мне так и не удалось. Выливалось это все в ошибку 502 Bad Gateway о которой скромненько так сообщал nginx. Но сам nginx тут ни при чем, он просто сообщает клиенту о том что бэкенд в данном случае php запущенный как FastCGI сервер не смог обработать скрипт и вернуть должный ответ фронтенду. Перепробовал много чего. И переход на unix socket и смена версий php, но это в конечно итоге ничего не дало. Самое плохое то что сам демон php-cgi вообще умирал, и единственный вариант возобновить работу это рестартануть его. Spawn-fcgi это такая «обертка» к php-cgi дающая некоторые возможности. Например имеющийся в ArchWiki скрипт запуска fcgi сервера запускался от рута и соответственно php у нас работал от суперпользователя, что не есть хорошо. К тому же всего один чайлд php (child) это мало и при большой нагрузке похапе падал. Например при натравливании бенчмарка httperf на мой блог с количеством 300 подключений и запросами каждые 10 секунд похапе валилось через 5 секунд. Параметры запуска httperf были такие:

httperf --client=0/1 --server=localhost --port=80
 --uri=/wordpress/ --rate=10 --send-buffer=4096
--recv-buffer=16384 --num-conns=300 --num-calls=1

Вобщем ближе к делу. Соберем spawn-fcgi все из того же AUR Далее нам потребуется самая важная часть — скрипт для его запуска. В собранном пакете из AUR’a его не будет. Я нашел на каком то ресурсе базовый скрипт и немного подправил его под свои реалии, выглядит он так:


#!/bin/bash
# general config
. /etc/rc.conf
. /etc/rc.d/functions
export PHP_FCGI_CHILDREN=20
export PHP_FCGI_MAX_REQUESTS=1024
case "$1" in
start)
check_config
stat_busy "Starting PHP5"
if [ -s /var/run/php5-fcgi.pid ]; then
stat_fail
# probably ;)
stat_busy "PHP5 is already running"
stat_die
fi
/usr/bin/spawn-fcgi -s /var/run/php-fcgi.sock -P /var/run/php5-fcgi.pid -u http -f /usr/bin/php-cgi &>/dev/null
if [ $? -ne 0 ]; then
stat_fail
else
add_daemon php5-fcgi
stat_done
fi
;;
stop)
stat_busy "Stopping PHP5"
kill -TERM `cat /var/run/php5-fcgi.pid`
if [ $? -ne 0 ]; then
stat_fail
else
rm_daemon php5-fcgi
stat_done
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
reload)
check_config
if [ -s /var/run/php5-fcgi.pid ]; then
status "Reloading PHP5 Configuration" kill -HUP `cat /var/run/php5-fcgi.pid`
fi
;;
check)
check_config
;;
*)
echo "usage: $0 {start|stop|restart|reload|check}"
esac;

Хочу обратить внимание на некоторые строки.

export PHP_FCGI_CHILDREN=5 export PHP_FCGI_MAX_REQUESTS=1000

Тут мы указали что процессов php будет целых 5 штук, вместо одного при обычном запуске php-cgi. Такое количество конечно скажется на памяти, но лучше отдать памяти на 200Мб больше чем смотреть на падения похапе. Второй строкой указываем что максимальное количество запросов к php будет ограничено одной тысячей.

/usr/bin/spawn-fcgi -s /var/run/php-fcgi.sock -P
/var/run/php5-fcgi.pid -u http -f /usr/bin/php-cgi

Здесь я указал что php будет слушать не по TCP/IP, а на unix сокете, потому как по TCP/IP итак много чего гоняется. Хотя вы можете сделать и 127.0.0.1:9000 Параметр -u указывает на то от какого пользователя будем запускать, у меня это http. -P соответственно расположение pid файла. Если вы будете использовать unix socket то в nginx.conf в секции location (или на уровне сервера) надо прописать так

fastcgi_pass   unix:/var/run/php-fcgi.sock;

Сохраняем наш скрипт в /etc/rc.d/spawn-fcgi даем права на исполнение:

sudo chown 755 /etc/rc.d/spawn-fcgi

и пробуем запустить его

sudo /etc/rc.d/spawn-fcgi start

Также в /etc/php.ini я увеличил количество памяти отдаваемую на выполнение скрипта параметром

memory_limit = 100M

Теперь похапе не валится и работает стабильно. Далее провел такой же бенч с блогом только количество подключений было не 300 а 500 и запросами каждые 10 сек. Специально прогнал бенч 5 раз и оно таки не упало. Можно еще собрать php с патчем fpm но у меня не вышло. Во первых потому что php-fpm на момент написания статьи существует только для php-5.3.0 а в Arch Linux уже давно 5.3.2 5.3.0 у меня вообще отказалось собираться хоть с патчем хоть без него ругаясь на gpm. Но скоро говорят что php-fpm включат в основную ветку, а пока пусть работает так.

Оцените статью