Настройка связки Nginx - Apache - FastCGI

В предыдущей статье "Установка и настройка веб сервера Nginx в качестве проксирующего фронтэнда к Apache", был рассмотрен простой вариант установки и использования Nginx, с настройками по-умолчанию, в качестве проксирующего сервера, с сервером Apache в качестве проксиркемого бакэнда.

В данном материале хотелось-бы рассказать о более сложном варианте установки и настройки Nginx, для построения связки Nginx Apache FastCGI. Для организации FastCGI сервера, будет использована утилиты, spawn-fcgi, ранее входившая в состав веб сервера lighttpd, а теперь выделенная в отдельный порт.

Схема работы связки Nginx Apache FastCGI, выглядит следующим образом:

схема работы связки 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 сервером, можно создать файл следующего содержания:

  1. <?php
  2. phpinfo();
  3. ?>

и положить его в корневую директорию документов сайта. Теперь запросив его через браузер, мы увидим страницу PHP, с кучей различной технической информации, включая опции сборки, настройки, модули, расширения, конфигурационные файлы и т.д. Находим строку Server API, и видим в каком режиме работает PHP на данном хосте, это у нас, CGI/FastCGI, то есть, то что нам и было нужно.

Проверить, что и остальные Location, отрабатывают должным образом, передавая запросы бакэндам, можно так, создать необходимый файл, запросить его через строку браузера и проверить лог файлы. То есть, запрос к файлу test.pl, можно будет обнаружить в файле access.log, виртуального хоста, сервера Apache, а запрос к файлу test.html, в лог файле веб сервера Nginx.

На этом пока хотелось-бы закончить. Удачи.

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Доступны HTML теги: <em> <strong> <code> <ul> <ol> <li>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

КАПЧА
Регистр имеет значение
                                                                .oooooo.    
d8P' `Y8b
oooo ooo oooooooo .oooooooo oooo ooo .oooo. 888
`88b..8P' d'""7d8P 888' `88b `88. .8' `P )88b 888
Y888' .d8P' 888 888 `88..8' .oP"888 888 ooooo
.o8"'88b .d8P' .P `88bod8P' `888' d8( 888 `88. .88'
o88' 888o d8888888P `8oooooo. `8' `Y888""8o `Y8bood8P'
d" YD
"Y88888P'
Введите код, изображенный в стиле ASCII-арт.