Сегодня мы поговорим о поднятии высокопроизводительно веб-сервера на основе nginx и турбированного патчем fpm php-демона.
Сейчас ни для кого не секрет, что nginx является чуть ли не идеальным фронт-эндом. В качестве бек-энда сейчас часто используется старый добрый веб-сервер Apache, но при серьезных нагрузках на машину (высокая посещаемость сайта или выполнение требовательных к ресурсам задач) апач ведет себя как корова на льду: виснет, падает, жрет память, но не работает как надо. Да, апач хорош, ибо искаропки умеет php, но это только для баловства. Как веб-сервер для серьезных задач он не подходит категорически.
Сегодня речь пойдет о связке nginx+php-fpm как замена апачу.
Вы спросите: зачем заменять апач, если он и так хорош? За ответом я пошлю вас в гугл смотреть тесты производительности apache (1 и 2 версии. кстати 1.3 ведет себя живее чем 2) с упомянутой выше связкой.
Предупреждаю сразу: если посещаемость вашего сайта(ов) не велика, то советую пройти мимо этой статьи и продолжать использовать apache в качестве бек-энда для генерации динамики. Но можете прочитать статью, настроить, посмотреть и в принципе не увидеть разницы.
Делать все будем на CentOS 5 версии. На других дистрибутивах ничего сильно отличающегося нет, поэтому вполне подойдет и для остальных (за исключением того, что придется искать нужные пакеты на стороне и возможно в ручную патчить php). Хотел написать еще и для Gentoo, но пользователи данного дистрибутива и без того умные люди (ибо дурак не смог бы с ней работать), поэтому сами смогут решить задачу.
Поехали.
Проверяем наличие доступа к репозиторию EPEL. Если вы используете репозитории SAN, то значит все хорошо.
Устанавливаем nginx:
- Код: Выделить всё • Развернуть
# yum install nginx
Подключаем репозиторий Varien следующим образом:
- Код: Выделить всё • Развернуть
# cd /etc/yum.repos.d
# wget http://mirrors.nslp.ru/centos/nslp.repo
Далее выполняем попытку обновления системы:
- Код: Выделить всё • Развернуть
# yum -y update
Если у вас уже стоят версии php младше 5.2.13 или php ручной компиляции, то ничего страшного. При обновлении установятся свежие (относительно) и главное вполне стабильные php-пакеты.
Если php не стоит (странно О_о), то устанавливаем:
- Код: Выделить всё • Развернуть
# yum install php php-gd php-mbstring php-mcrypt
Устанавливаем гвоздь нашей программы:
- Код: Выделить всё • Развернуть
# yum install php-fpm
Рассматривать установку и настройку mysql мы не будем. Сами разберетесь.
Теперь у нас имеется легковесный веб-сервер и пропатченая версия php-cgi. Но nginx вообще не умеет генерировать динамику (коими являются php-скрипты), поэтому начнем прикручить php-fpm к nginx.
Для начала открываем конфиг php-fpm и приводим его в божеский вид. Описывать каждую строчку не буду. Если интересно, то это вам задание на самостоятельную подготовку.
- Код: Выделить всё • Развернуть
# nano /etc/php-fpm.conf
Приводим конфиг к следующему виду:
- Код: Выделить всё • Развернуть
<configuration>
<section name="global_options">
<value name="pid_file">/var/run/php-fpm.pid</value>
<value name="error_log">/var/log/php-fpm.log</value>
<value name="log_level">notice</value>
<value name="emergency_restart_threshold">10</value>
<value name="emergency_restart_interval">1m</value>
<value name="process_control_timeout">5s</value>
<value name="daemonize">yes</value>
</section>
<workers>
<section name="pool">
<value name="name">default</value>
# <value name="listen_address">/tmp/fcgi.sock</value>
<value name="listen_address">127.0.0.1:9000</value>
<value name="listen_options">
<value name="owner"></value>
<value name="group"></value>
<value name="mode">0666</value>
</value>
<value name="php_defines">
</value>
<value name="user">nginx</value>
<value name="group">nginx</value>
<value name="pm">
<value name="style">static</value>
<value name="max_children">10</value>
<value name="apache_like">
<value name="StartServers">20</value>
<value name="MinSpareServers">5</value>
<value name="MaxSpareServers">35</value>
</value>
</value>
<value name="request_terminate_timeout">0s</value>
<value name="request_slowlog_timeout">0s</value>
<value name="slowlog">logs/slow.log</value>
<value name="rlimit_files">1024</value>
<value name="rlimit_core">0</value>
<value name="chroot"></value>
<value name="chdir"></value>
<value name="catch_workers_output">yes</value>
<value name="max_requests">500</value>
<value name="allowed_clients">127.0.0.1</value>
<value name="environment">
<value name="HOSTNAME">$HOSTNAME</value>
<value name="PATH">/usr/local/bin:/usr/bin:/bin</value>
<value name="TMP">/tmp</value>
<value name="TMPDIR">/tmp</value>
<value name="TEMP">/tmp</value>
<value name="OSTYPE">$OSTYPE</value>
<value name="MACHTYPE">$MACHTYPE</value>
<value name="MALLOC_CHECK_">2</value>
</value>
</section>
</workers>
</configuration>
Обратите внимание на строчку
- Код: Выделить всё • Развернуть
<value name="listen_address">127.0.0.1:9000</value>
Это адрес и порт, на котором будет висеть и слушать php-демон. Закомментированная строчка выше- использование unix-сокета для той же задачи. Вопрос о том, что эффективнее спорный: одни говорят что вешание демона на сокет эффективнее, другие считают наоборот.
Пробуем запустить php
- Код: Выделить всё • Развернуть
# service php-fpm start
или
- Код: Выделить всё • Развернуть
# /etc/init.d/php-fpm start
Если в консоли появилось нечто вроде
- Код: Выделить всё • Развернуть
[root@server etc]# /etc/init.d/php-fpm start
Запускается php-fpm: [ OK ]
значит все хорошо и php в данный момент висит на 9000 порту ожидая запросов.
Теперь настраиваем nginx на перенаправление запросов к php-страницам на php-fpm.
Конфиг /etc/nginx/nginx.conf будет приблизительно следующим:
- Код: Выделить всё • Развернуть
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# Load config files from the /etc/nginx/conf.d directory
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name mydomain.com;
location / {
root /var/www/mydomain;
index index.php index.html index.htm;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/mydomain$fastcgi_script_name;
include fastcgi_params;
}
}
}
}
В данном примере наш сайт лежит в дериктории /var/www/mydomain и имеет адрес mydomain.com. Указана корневая дериктория хоста (/var/www/mydomain). Далее, если идет запрос на php-страницу, то nginx переадресовывет его на php-cgi, который висит на 9000 порту. После обработки запроса php-демоном, nginx возвращает ответ клиенту.
Вот в принципе и все.
Добавляем nginx и php-fpm в автозагрузку
- Код: Выделить всё • Развернуть
# chkconfig --level 345 add nginx on
# chkconfig --level 345 add php-fpm on
Вот собственно и все. Не используя apache мы получили неплохой и производительный веб-сервер.
Статья полностью написана мною. При перепечатке или копировании ссылка на данную статью и автора обязательна.
Замечания и предложения приветствуются.