В предыдущей статье "Установка и настройка веб сервера 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.
На этом пока хотелось-бы закончить. Удачи.