Application: Zabbix Server, Nginx, PHP, FastCGI.
Zabbix - прекрасная комплексная система мониторинга, удивляюсь тому, как разработчики умудряются проработать массу взаимосвязей таким образом, что они отлично работают. Вот только интерфейс явно притормаживает даже на самых что ни на есть мощных серверах. "Web"-сервер, предлагаемый разработчиками по умолчанию - Apache, весьма монструозный для достаточно простой задачи, как отрисовка графиков на выделенной физической машине. Нужно что-то пошустрее и полегче. Я остановился на Nginx.
Nginx включает в себя поддержку технологии FastCGI для работы с внешними серверами и утилитами. PHP так же поддерживает FastCGI и может быть использован для обработки FastCGI-запросов от Nginx.
Для начала установим PHP с поддержкой технологии FastCGI и запустим его на каком-нибудь TCP локального интерфейса. Получится своего рода PHP FastCGI сервер. После на этот сервер будем переправлять запросы из Nginx.
# aptitude install php5 php5-cgi php5-gd php5-pgsql psmisc
После установки PHP необходимо несколько изменить файл его настройки, адаптируя интерпретатор к условиям эксплуатации в "Linux Debian Lenny/Squeeze" (требуется обеспечить поддержку правильных трансляций "PATH_INFO/PATH_TRANSLATED" в FastCGI) и требованиям Zabbix. Для этого необходимо отредактировать файл "/etc/php5/cgi/php.ini" таким образом, чтобы ряд переменных приняли следующие значения:
....
cgi.fix_pathinfo = 1
....
date.timezone = Country/Town
memory_limit = 256M
post_max_size = 32M
upload_max_filesize = 16M
max_execution_time = 600
max_input_time = 600
....
cgi.fix_pathinfo = 1
....
date.timezone = Country/Town
memory_limit = 256M
post_max_size = 32M
upload_max_filesize = 16M
max_execution_time = 600
max_input_time = 600
....
Значение параметра "date.timezone" берем из системного файла"/etc/timezone".
Теперь можно попробовать запустить PHP-CGI:
# /usr/bin/php-cgi
Если не наблюдается никаких ошибок, то вероятнее всего интерпретатор работает корреткно. Прерываем его работу нажатием комбинации "Ctrl+C", чтобы завершить процесс.
Есть, как минимум, два варианта запуска автономного FastCGI сервера:
Запуск встроенного в интерпретатор PHP сервера FastCGI - метод, не требующий никаких дополнительных утилит;
Запуск PHP внутри какого-либо стороннего обработчика запросов - этот вариант может быть более удобным из-за большей гибкости в настройке.
Запуск PHP внутри какого-либо стороннего обработчика запросов - этот вариант может быть более удобным из-за большей гибкости в настройке.
С учётом того, что я, по возможности, всегда стараюсь не использовать избыточного программного обеспечения - остановимся на запуске встроенного в PHP FastCGI сервера.
Будет проще управлять нашим PHP FastCGI сервером, сославшись на него особенным именем, используемым только в одной схеме:
# ln -s /usr/bin/php-cgi /usr/local/bin/php-cgi-zabbix
Добавим в систему пользователя, от имени которого будем запускать сервер FastCGI:
# groupadd php-fcgi-zabbix
# useradd --home-dir /var/lib/php-fcgi-zabbix --shell /bin/false --gid php-fcgi-zabbix php-fcgi-zabbix
# useradd --home-dir /var/lib/php-fcgi-zabbix --shell /bin/false --gid php-fcgi-zabbix php-fcgi-zabbix
Создадим ему место жительства:
# mkdir -p /var/lib/php-fcgi-zabbix
# chown -R php-fcgi-zabbix:php-fcgi-zabbix /var/lib/php-fcgi-zabbix
# chown -R php-fcgi-zabbix:php-fcgi-zabbix /var/lib/php-fcgi-zabbix
Пишем простенький скрипт запуска FastCGI PHP сервера:
# touch /usr/local/bin/php-fcgi-zabbix
# chmod ugo+x /usr/local/bin/php-fcgi-zabbix
# chmod ugo+x /usr/local/bin/php-fcgi-zabbix
#!/bin/bash
# Путь к исполняемому файлу PHP запускаемому как FastCGI сервер
PHPFCGI="/usr/local/bin/php-cgi-zabbix"
# Прослушиваемый CGI сервером адрес
FCGIADDR="127.0.0.1"
# Прослушиваемый CGI сервером порт
FCGIPORT="8888"
# Пользователь, от имени которого мы запускаем CGI сервер
USER="php-fcgi-zabbix"
# Указываем в переменной окружения количество дочерних потоков, запускаемых для обработки запросов
export PHP_FCGI_CHILDREN=8
# Указываем максимальное количество запросов для обработки процессом CGI сервера
export PHP_FCGI_MAX_REQUESTS=1000
/bin/su --preserve-environment --login "${USER}" --command "${PHPFCGI} -b ${FCGIADDR}:${FCGIPORT}" &
exit 0
# Путь к исполняемому файлу PHP запускаемому как FastCGI сервер
PHPFCGI="/usr/local/bin/php-cgi-zabbix"
# Прослушиваемый CGI сервером адрес
FCGIADDR="127.0.0.1"
# Прослушиваемый CGI сервером порт
FCGIPORT="8888"
# Пользователь, от имени которого мы запускаем CGI сервер
USER="php-fcgi-zabbix"
# Указываем в переменной окружения количество дочерних потоков, запускаемых для обработки запросов
export PHP_FCGI_CHILDREN=8
# Указываем максимальное количество запросов для обработки процессом CGI сервера
export PHP_FCGI_MAX_REQUESTS=1000
/bin/su --preserve-environment --login "${USER}" --command "${PHPFCGI} -b ${FCGIADDR}:${FCGIPORT}" &
exit 0
После запуска скрипта можно наблюдать в списке процессов подтверждение того, что PHP FastCGI сервер успешно запущен:
# ps axu --forest | grep php-cgi
php-fcgi .... S /bin/su --preserve-environment --login php-fcgi --command /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
php-fcgi .... Ss \_ /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
php-fcgi .... S \_ /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
php-fcgi .... S \_ /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
....
php-fcgi .... Ss \_ /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
php-fcgi .... S \_ /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
php-fcgi .... S \_ /usr/local/bin/php-cgi-zabbix -b 127.0.0.1:8888
....
Пишем скрипт автоматического запуска и перезапуска нашего FastCGI сервера:
# touch /etc/init.d/php-fcgi-zabbix-init
# chmod ugo+x /etc/init.d/php-fcgi-zabbix-init
# chmod ugo+x /etc/init.d/php-fcgi-zabbix-init
#!/bin/bash
### BEGIN INIT INFO
# Provides: php-fcgi-zabbix-init
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Start PHP FastCGI daemon for Zabbix
### END INIT INFO
EXEC="php-cgi-zabbix"
WRAPPER="/usr/local/bin/php-fcgi-zabbix"
case "$1" in
start)
echo "Initializing PHP-FCGI processes ..."
${WRAPPER}
;;
stop)
echo "Terminating PHP-FCGI processes ..."
killall ${EXEC}
;;
restart)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
### BEGIN INIT INFO
# Provides: php-fcgi-zabbix-init
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Start PHP FastCGI daemon for Zabbix
### END INIT INFO
EXEC="php-cgi-zabbix"
WRAPPER="/usr/local/bin/php-fcgi-zabbix"
case "$1" in
start)
echo "Initializing PHP-FCGI processes ..."
${WRAPPER}
;;
stop)
echo "Terminating PHP-FCGI processes ..."
killall ${EXEC}
;;
restart)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
Прописываем наш скрипт для всех уровней исполнения в системе:
# update-rc.d php-fcgi-zabbix-init start 10 2 3 4 5 . stop 10 0 1 6 .
Управление элементарно:
# /etc/init.d/php-fcgi-zabbix-init {start|stop|restart}
Теперь инсталлируем Nginx:
# aptitude install nginx
Общая конфигурация Nginx находится в файле "/etc/nginx/nginx.conf", конфигурации хостов и сайтов описываются в файлах, располагающихся в директориях "/etc/nginx/conf.d." и "/etc/nginx/sites-enabled.", подключаемых с помощью директив "include /etc/nginx/conf.d/*.conf;" и "include /etc/nginx/sites-enabled/*;".
Приведём общий конфигурационный файл "/etc/nginx/nginx.conf" к следующему виду:
# Указываем пользователя и группу, от чьего имени запускается Nginx
user www-data www-data;
# Количество запускаемых рабочих процессов приравняем к количеству процессорных ядер на нашем сервере
worker_processes 4;
# Указываем месторасположение журнального файла сообщений об ошибках
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
# Подключаем описание типов файлов
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Месторасположение журнального файла событий доступа
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
tcp_nodelay on;
# Запрещаем сообщать версию Nginx в ответе клиенту
server_tokens off;
# Подключаем файлы описания дополнительных конфигураций
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
user www-data www-data;
# Количество запускаемых рабочих процессов приравняем к количеству процессорных ядер на нашем сервере
worker_processes 4;
# Указываем месторасположение журнального файла сообщений об ошибках
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
# Подключаем описание типов файлов
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Месторасположение журнального файла событий доступа
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
tcp_nodelay on;
# Запрещаем сообщать версию Nginx в ответе клиенту
server_tokens off;
# Подключаем файлы описания дополнительных конфигураций
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Создаем файл конфигурации виртуального хоста "zabbix.local":
# touch /etc/nginx/sites-available/zabbix.local
Приводим его к следующему виду:
server {
listen *:80;
server_name zabbix.local;
# Указываем кодировку отдаваемых страниц
charset utf-8;
root /var/www/zabbix.local;
index index.php;
# Запрещаем отдавать кому бы то ни было файлы .htaccess и .htpasswd
location ~* /\.ht {
deny all;
}
# Ограничиваем доступ к ряду директорий в соответствии с рекомендациями разработчиков Zabbix
location ~* /(api|conf|include)/ {
rewrite ^/(.*)$ http://zabbix.local/index.php permanent;
}
# Секция описания перенаправления PHP скриптов на исполнение CGI серверу
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/zabbix.local$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_pass 127.0.0.1:8888;
# Указываем Nginx передавать ответы FastCGI-сервера с кодом больше или равными "400" директивам "error_page" для дальнейшей отработки
fastcgi_intercept_errors on;
# Описываем реакцию на ошибочные ситуации
error_page 403 404 502 503 504 http://zabbix.local/index.php;
}
}
listen *:80;
server_name zabbix.local;
# Указываем кодировку отдаваемых страниц
charset utf-8;
root /var/www/zabbix.local;
index index.php;
# Запрещаем отдавать кому бы то ни было файлы .htaccess и .htpasswd
location ~* /\.ht {
deny all;
}
# Ограничиваем доступ к ряду директорий в соответствии с рекомендациями разработчиков Zabbix
location ~* /(api|conf|include)/ {
rewrite ^/(.*)$ http://zabbix.local/index.php permanent;
}
# Секция описания перенаправления PHP скриптов на исполнение CGI серверу
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/zabbix.local$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_pass 127.0.0.1:8888;
# Указываем Nginx передавать ответы FastCGI-сервера с кодом больше или равными "400" директивам "error_page" для дальнейшей отработки
fastcgi_intercept_errors on;
# Описываем реакцию на ошибочные ситуации
error_page 403 404 502 503 504 http://zabbix.local/index.php;
}
}
Указываем символической ссылкой Nginx на доступную конфигурацию виртуального хоста:
# ln -s /etc/nginx/sites-available/zabbix.local /etc/nginx/sites-enabled/zabbix.local
Удаляем ссылку на конфигурацию виртуально хоста "по умолчанию":
# rm /etc/nginx/sites-enabled/default
Перезапускаем Nginx:
# /etc/init.d/nginx restart
По завершению конфигурирования Nginx закрываем от постороннего взгляда директорию конфигурации:
# chown -R root:root /etc/nginx
# chmod -R o-rwx /etc/nginx
# chmod -R o-rwx /etc/nginx
Теперь доля "web"-сервера в потреблении ресурсов существенно уменьшилась. Если раньше в "топе" процессов с максимальным потреблением ресурсов процессора и оперативной памяти Apache присутствовал постоянно, но теперь там "прописался" PHP, который ранее занимал вторые места. Nginx же вообще находится в списке за нижней части экрана.
24 ноября 2010 в 04:30
24 ноября 2010 в 20:07