Настройка связки Nginx Apache FastCGI
В предыдущей статье "Установка и настройка веб сервера Nginx в качестве проксирующего фронтэнда к Apache", был рассмотрен простой вариант установки и использования Nginx, с настройками по-умолчанию, в качестве проксирующего сервера, с сервером Apache в качестве проксиркемого бакэнда.
В данном материале хотелось-бы рассказать о более сложном варианте установки и настройки Nginx, для построения связки Nginx Apache FastCGI. Для организации FastCGI сервера, будет использована утилиты, spawn-fcgi, ранее входившая в состав веб сервера lighttpd, а теперь выделенная в отдельный порт.
Схема работы связки Nginx - Apache - FastCGI, выглядит следующим образом:
Теперь на словах. Все запросы приходят на адрес, на котором сервер Nginx принимает соединения. Согласно настройкам в конфигурационном файле Nginx:
- Все статические запросы ( HTML файлы, картинки ), будут обработаны веб сервером Nginx самостоятельно, после чего результат будет выдан клиенту;
- Запросы к CGI и Perl ( файлы CGI, PL ) скриптам, будут отправлены на обработку Apache, после обработки, результат будет передан в Nginx и отдан клиенту;
- Все запросы к скриптам PHP, будут перенаправлены на сервер FastCGI, после обработки, результат опять-же будет возвращен в Nginx и выдан клиенту;
Итак, что мы имеем: операционная система FreeBSD 7.1 STABLE ( платформа amd64 ), установленный веб сервер Apache/2.2.9. Установка Nginx производилась со следующими опциями:
vds-admin$ nginx -V nginx version: nginx/0.7.61 built by gcc 4.2.1 20070719 [FreeBSD] configure arguments: --prefix=/usr/local/etc/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/usr/local/etc/nginx/conf/nginx.conf --error-log-path=/usr/local/etc/nginx/logs/error.log --with-http_stub_status_module --user=www
PHP с поддержкой FastCGI интерфейса
Настройку сервера Nginx, сделаем чуть позже, сначала настроим FastCGI сервер, установив все необходимое. Что вообще такое, FastCGI. В общем понимании, это протокол взаимодействия, между веб сервером и приложением, не зависимый от языка приложения и являющийся куда более производительным и безопасным, нежели обычный CGI. Если коротко, обычную CGI программу, веб серверу, приходится запускать на каждый запрос, в то время как FastCGI, постоянно держит запущенный процесс, который и обслуживает приходящие ему запросы. Кроме того веб сервер, связывается с FastCGI сервером, через так называемый "Unix domain socket" или через TCP/IP, в отличии от обычного CGI, который взаимодействует с сервером через стандартный ввод/вывод, что дает возможность располагать FastCGI сервер, не только в рамках одной машины, но и вообще где угодно в сети.
В контексте данного материала, речь идет о языке PHP, собранном с поддержкой FastCGI и запущенном с помощью специального приложения.
Для поддержки данного режима работы, PHP, должен быть скомпилирован с соответствующими опциями и иметь необходимый бинарник ( запускаемый файл, по умолчанию php-cgi.) Следующие опции необходимы для сборки PHP с поддержкой FasCGI и обеспечения необходимого уровня безопасности:
--enable-fastcgi
--enable-force-cgi-redirect
--enable-discard-path
Остальные опции ставите в зависимости от ваших потребностей.
Посмотреть опции, с которыми собран PHP, можно так:
vds-admin$root/ php -i | grep configure Configure Command => './configure' '--with-layout=GNU' '--with-config-file-scan-dir=/usr/local/etc/php' '--disable-all' '--enable-libxml' '--with-libxml-dir=/usr/local' '--enable-reflection' '--program-prefix=' '--enable-force-cgi-redirect' '--enable-discard-path' '--enable-fastcgi' '--with-apxs2=/usr/local/sbin/apxs' '--with-regex=php' '--with-zend-vm=CALL' '--enable-zend-multibyte' '--disable-ipv6' '--prefix=/usr/local' '--mandir=/usr/local/man' '--infodir=/usr/local/info/' '--build=amd64-portbld-freebsd7.1'
Установка и настройка spawn-fcgi для запуска FastCGI сарвера PHP
Процесс сборки и установки длится меньше минуты. По завершению, будет создано несколько файлов:
/usr/local/bin/spawn-fcgi #Запускаемый файл программы
/usr/local/etc/rc.d/spawn-fcgi #Cтартовый скрипт, для запуска FastCGI сервера
Как правило я использую Unix Socket для связи сервера Nginx с FastCGI сервером ( хотя в случае возникновения проблем, можно использовать TCP/IP ), поэтому идем править стартовый скрипт, приведя его переменные к такому виду:
: ${spawn_fcgi_app="/usr/local/bin/php-cgi"} #Приложение для запуска : ${spawn_fcgi_pidfile="/var/run/spawn-fcgi.pid"} #Файл содержащий ID процесса : ${spawn_fcgi_user="www"} #Пользователь, под которым будет выполняться приложение : ${spawn_fcgi_group="www"} #Группа : ${spawn_fcgi_socket="/tmp/fastcgi_sock"} #Файл Unix сокета #: ${spawn_fcgi_bindaddr="127.0.0.1"} #В данном случае мы не используем TCP/IP #: ${spawn_fcgi_bindport="9000"} : ${spawn_fcgi_children="5"} #Количество дочерних процессов php-cgi : ${spawn_fcgi_max_requests="1000"} #Количество обслуженных запросов, после которого дочерний процесс будет перезапущен : ${spawn_fcgi_web_server_addrs=""} : ${spawn_fcgi_allowed_env=""} : ${spawn_fcgi_path_env="/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin"} command="/usr/local/bin/spawn-fcgi" command_args="-u ${spawn_fcgi_user} -g ${spawn_fcgi_group} -P ${spawn_fcgi_pidfile} -s ${spawn_fcgi_socket} -- ${spawn_fcgi_app}" #Это собственно и есть команда запуска со всеми необходимыми аргументами.
Полный список опций программы spawn-fcgi, приведен тут Spawn-fcgi запуск процессов в FastCGI режиме
Не забываем добавить строку spawn_fcgi_enable="YES" в стартовый скрипт /etc/rc.conf, для запуска FastCGI сервера при старте системы.
vds-admin$ echo "spawn_fcgi_enable=YES" >> /etc/rc.conf
Пробуем запустить spawn-fcgi:
vds-admin/# /usr/local/etc/rc.d/spawn-fcgi start Starting spawn_fcgi. spawn-fcgi: child spawned successfully: PID: 33019 #Проверяем наличие запущенных процессов: vds-admin/# ps aux | grep php www 33019 0.0 1.5 92332 15832 ?? Ss 5:01PM 0:00.08 /usr/local/bin/php-cgi www 33020 0.0 1.5 92332 15872 ?? S 5:01PM 0:00.00 /usr/local/bin/php-cgi www 33021 0.0 1.5 92332 15872 ?? S 5:01PM 0:00.00 /usr/local/bin/php-cgi www 33022 0.0 1.5 92332 15872 ?? S 5:01PM 0:00.00 /usr/local/bin/php-cgi www 33023 0.0 1.5 92332 15872 ?? S 5:01PM 0:00.00 /usr/local/bin/php-cgi www 33024 0.0 1.5 92332 15872 ?? S 5:01PM 0:00.00 /usr/local/bin/php-cgi #Проверяем наличие соответствующего сокета: vds-admin$ netstat -Lan Current listen queue sizes (qlen/incqlen/maxqlen) Proto Listen Local Address .................................... unix 0/0/128 /tmp/fastcgi_sock #Наш FastCGI сокет для работы с веб-сервером Nginx ....................................
FastCGI сервер готов к работе
Настройка веб сервера Apache
Настройка сервера Apache, аналогична той, которую мы делали в статье "Установка и настройка веб сервера Nginx в качестве проксирующего фронтэнда к Apache". То есть задача сводится к смене IP адреса и, если необходимо, порта, на которых веб-сервер Apache будет принимать запросы от Nginx и опять-же по мере надобности, настройка виртуальных хостов, так-же затронутая в вышеприведенной статье. Напомню, сервер Apache будет принимать соединения на локальном адресе 127.0.0.1, порт 80. Кроме того, все в той-же статье, мы настроили модуль сервера Apache, mod_rpaf, для передачи в Apache, реальных адресов клиентов, а не внутреннего адреса сервера Nginx.
Настройка веб сервера Nginx, на работу с бакэндами, Apache и FastCGI
Опции с которыми был установлен сервер Nginx, приводились выше, то есть по сути, это "умолчальная" установка, изменены некоторые пути, как мне привычней и включен модуль для просмотра статусной страницы Nginx.
Перейдем к конфигурационному файлу.
Хотелось-бы отметить, что окончательный вид конфигурационного файла Nginx, зависит от вашей конкретной системы, то есть например, различные таймауты, размеры и количество буферов, передаваемые заголовки и т.д., должны быть установлены, исходя из задач, решаемых на данном сервере. Поэтому давать рекомендации в стиле, "поставьте этого столько а того столько и напишите это.. потому что у меня это работает.. ", считаю неуместным.
Здесь у нас рабочий вариант конфигурационного файла nginx, так сказать, без наворотов, лишь необходимый минимум. Выглядит он у нас следующим образом:
user www; worker_processes 1; error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include 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 logs/access.log main; sendfile on; tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; reset_timedout_connection on; #gzip on; server { listen 192.168.50.20:80; # Внешний IP адрес, на котором Nginx принимает соединения server_name nginxhost; # Имя хоста #charset koi8-r; access_log logs/host.access.log main; root /home/nginxhost/public_html; ############################################## location / { index index.html index.htm; } location ~* \.(jpeg|jpg|png|gif){ expires max; } # Данные две секции Location, будет обрабатывать Nginx ############################################# ################# Apache ##################### location ~ \.(pl|cgi)$ { proxy_pass http://127.0.0.1; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Запросы соответствующие этому Location, будут переданы на обработку веб серверу Apache ############################################# ################## FastCGI ##################### location ~ \.php$ { fastcgi_pass unix:/tmp/fastcgi_sock; # Сокет для связи с FastCGI fastcgi_index index.php; # Индексный файл fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #Переменная $document_root, содержит путь к корневой папке дерева документов #переменная $fastcgi_script_name, содержит имя запрошенного файла скрипта include fastcgi_params; # Включение файла с fastcgi параметрами, передаваемыми fastcgi серверу } # Эти запросы будут переданы для обработки FastCGI серверу ############################################# location ~ /\.ht { deny all; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
Проверяем правильность файла конфигурации:
vds-admin$ nginx -t the configuration file /usr/local/etc/nginx/conf/nginx.conf syntax is ok configuration file /usr/local/etc/nginx/conf/nginx.conf test is successful
Все в порядке, можно запускать
vds-admin$ nginx
Проверим что у нас там показывает netstat:
vds-admin$ netstat -Lan Current listen queue sizes (qlen/incqlen/maxqlen) Proto Listen Local Address tcp4 0/0/128 192.168.50.20.80 #Cервер Nginx ( фронтэнд ) ......................... tcp4 0/0/128 127.0.0.1.80 #Сервер Apache ( бакэнд 1 ) ......................... unix 0/0/128 /tmp/fastcgi_sock #Сервер FastCGI ( бакэнд 2 ) .........................
Теперь все это можно проверить через браузер, набрав имя хоста Nginx или IP адрес. Что-бы убедиться что PHP скрипты обрабатываются нашим FastCGI сервером, можно создать файл следующего содержания:
<?php
phpinfo();
?>
и положить его в корневую директорию документов сайта. Теперь запросив его через браузер, мы увидим страницу PHP, с кучей различной технической информации, включая опции сборки, настройки, модули, расширения, конфигурационные файлы и т.д. Находим строку Server API, и видим в каком режиме работает PHP на данном хосте, это у нас, CGI/FastCGI, то есть, то что нам и было нужно.
Проверить, что и остальные Location, отрабатывают должным образом, передавая запросы бакэндам, можно так, создать необходимый файл, запросить его через строку браузера и проверить лог файлы. То есть, запрос к файлу test.pl, можно будет обнаружить в файле access.log, виртуального хоста, сервера Apache, а запрос к файлу test.html, в лог файле веб сервера Nginx.
На этом пока хотелось-бы закончить. Удачи.
Комментарии
.htaccess будит работать при такой связке??
в той части, которую обрабатывает апач, да
У меня нивкакую не хочет работать .htaccess при такой связке, может подскажете где грабли могут быть, ну или мелкие фишки?
ну скорей всего эту чать не полностью обрабатывает апач..
.htaccess работает, когда вы делаете допустим proxy_pass на него, тобишь апач
приведите примерную схемку, что у вас есть и чего хотите получить
можно как нибудь в асю пообщаться?
Не обрабатывает правила
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Как быть?
Статья толковая и мне понравилась.
Но никак не могу заставить свою связку nginx/fastcgi работать.
nginx работает, отдаёт статичные файлы и бэкэнд к apache работает хорошо. Хочу поднять php/fpm.
fastcgi занимает сокет или порт, но не возвращая контент в nginx, возвращает статус 200.
$document_root и $fastcgi_script, судя по логам, возвращают корректные значения.
Доступ к корневой папке сервера для nobody на чтение есть.
access.log
error.log
nginx.conf
php-fpm.conf
Gentoo, php собран с cli, cgi, fpm, apache2
попробуйте с дебагом собрать, думаю там видней будет
Не знаю зачем тебе, но вот тут - http://joomlaforum.ru/index.php/topic,35335.150.html
конфигурация гникса описана с отрабатывающим .htaccess
там все запросы кроме картинок, летят на апач, поэтому там htaccess и работает
а тут на апач уходит только perl/cgi, ПХП обрабатывается на fastcgi сервере, все остальное nginx
Дань скорости обработки запроса... увы
Отправить комментарий