Сегодня мы затронем такую интересную тему как повышение скорости работы вашего сайта. Конечно же это и оптимизированный код и оптимизированные sql-запросы. Но есть и еще несколько мест, в которых производительность может падать. Одним из таких мест является http-сервер Apache. Есть целый ряд трюков, которые позволяют повысить пропускную способность этого узкого места. Один из таких трюков - установка вместо Apache более легковесного сервера. Одним из интересных решений может быть использование вместо Apache сервера Nginx, который разрабатывается Игорем Сысоевым.

Этот веб-сервер обладает немалыми возможностями. С полным их списком вы можете ознакомиться на официальном сайте. В данной статье пойдет речь о том как использовать вместо Apache этот замечательный сервер. Если ваш сервер на базе FreeBSD, то вот замечательная инструкция по установке Nginx в связке с php.

А наша статья конечно же для тех у кого Linux. Традиционно пример на основе openSUSE. Если у вас есть положительный или отрицательный опыт по данной теме с другими дистрибутивами, то напишите обязательно об этом в комментариях.

Итак начнем. Основная проблема в том, что у Nginx нет модуля mod_php. Однако он поддерживает технологию FastCGI для работы с внешними серверами и утилитами. PHP также поддерживает FastCGI и может быть использован для обработки FastCGI-запросов от nginx.

Существует 2 подхода

  1. Запуск встроенного в php сервера fastCGI
  2. Запуск php внутри стороннего обработчика запросов

Первый метод проще, а второй более гибок в настройках. Поэтому рассмотрим второй способ с использованием spawn-php.sh из пакета lighttpd.

Собирать все пакеты из исходников нам не придется. Если у кого-нибудь есть такая необходимость, то можете воспользоваться инструкцией для FreeBSD.

Для openSUSE мы возьмем lighttpd из репозитория  openSUSE-11-Updates, а сам nginx из репозитоия gwdg.

После этого нам надо настроить spawn-php.sh как отдельную службу (так как нам весь lighttpd не нужен). Копируем из пакета один только файл в удобное для нас место и задаем права на выполнение:

cp /usr/share/doc/packages/lighttpd/spawn-php.sh /usr/bin/spawn-php
chmod 775 /usr/bin/spawn-php

Теперь нам надо настроить данный скрипт под нашу систему. Поменяйте приведенную часть в соответствии со своими путями

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
 
## ABSOLUTE path to the spawn-fcgi binary
SPAWNFCGI="/usr/sbin/spawn-fcgi"
 
## ABSOLUTE path to the PHP binary
FCGIPROGRAM="/usr/bin/php-cgi"
 
## TCP port to which to bind on localhost
FCGIPORT="1026"
 
## number of PHP children to spawn
PHP_FCGI_CHILDREN=10
 
## maximum number of requests a single PHP 
##     process can serve before it is restarted
PHP_FCGI_MAX_REQUESTS=1000
 
## IP addresses from which PHP should access server connections
FCGI_WEB_SERVER_ADDRS="127.0.0.1,10.1.1.113"
 
# allowed environment variables, separated by spaces
ALLOWED_ENV="ORACLE_HOME PATH USER"
 
## if this script is run as root, switch to the following user
USERID=wwwrun
GROUPID=www

Впишите свои значения для SPAWNFCGI, FCGIPROGRAM, USERID и GROUPID. И обратите внимание на FCGIPORT. Это порт по которому будут общаться nginx и spawn-php. Его можно менять на свой вкус. Но надо чтобы он совпадал с настройками самого nginx (они будут приведены далее).
Теперь надо сделать чтобы при старте системы скрипт запускался. Конечно мы могли бы сделать очень просто. Поместив вызов скрипта либо в файл /etc/init.d/boot.local , либо в файл /etc/init.d/before.local вы получите его автозапуск. В первом случае скрипт выполняется в самом начале, сразу после запуска скриптов из /etc/init.d/boot.d, а во втором - непосредственно перед началом запуска выбранного runlevel-а. Но вот если вам понадобится перезагрузить или остановить этот fastcgi-сервер, то вам придется вспоминать как называется та программа, которую надо kill-нуть чтобы остановить сервер (Кстати, это php-cgi). Кого этот путь устраивает, те могут перейти уже к настройке nginx.
Мы же пойдем по правильному пути. Обернем скрипт таким образом чтобы он вел себя как демон. Для этого есть заготовка /etc/init.d/skeleton. У шаблона подробные комментарии и простая структура. Но все же я внес несколько изменений, которые ближе к нашей задаче. Вот листинг нашего нового файла /etc/init.d/spawn-php-demon:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/bin/sh
### BEGIN INIT INFO
# Provides:          spawn-php-demon
# Required-Start:    $syslog $remote_fs
# Should-Start: $time ypbind sendmail
# Required-Stop:     $syslog $remote_fs
# Should-Stop: $time ypbind sendmail
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: spawn-php-demon
# Description:       demon for using php as cgi for nginx
### END INIT INFO
SPAWNPHP_BIN=/usr/bin/spawn-php
PHP_CGI=/usr/bin/php-cgi
test -x $SPAWNPHP_BIN || { echo "Spawn-php not installed"; 
	if [ "$1" = "stop" ]; then exit 0;
	else exit 5; fi; }
 
 
. /etc/rc.status
 
# Reset status of this service
rc_reset
 
case "$1" in
    start)
	echo -n "Starting spawn-php "
	## Start daemon with startproc(8). If this fails
	## the return value is set appropriately by startproc.
	/sbin/startproc $SPAWNPHP_BIN
	/sbin/checkproc $PHP_CGI
	rc_status -v
	;;
    stop)
	echo -n "Shutting down spawn-php "
	## Stop daemon with killproc(8) and if this fails
	## killproc sets the return value according to LSB.
	/sbin/killproc -TERM $PHP_CGI
	# Remember status and be verbose
	rc_status -v
	;;
    restart)
	## Stop the service and regardless of whether it was
	## running or not, start it again.
	$0 stop
	$0 start
	# Remember status and be quiet
	rc_status
	;;
    status)
	echo -n "Checking for service spawn-php "
	## Check status with checkproc(8), if process is running
	## checkproc will return with exit status 0.
	# NOTE: checkproc returns LSB compliant status values.
	/sbin/checkproc $PHP_CGI
	# NOTE: rc_status knows that we called this init script with
	# "status" option and adapts its messages accordingly.
	rc_status -v
	;;
esac
rc_exit

Теперь мы очень удобно сможем останавливать и запускать службу. В openSUSE конечно же есть GUI для этих целей. Но в консоле быстрее.

linux-r2ch:/home/izumeroot # /etc/init.d/spawn-php-demon start
Starting spawn-php spawn-fcgi.c.197: child spawned successfully: PID: 5527
                                                                      done
linux-r2ch:/home/izumeroot # /etc/init.d/spawn-php-demon stop
Shutting down spawn-php                                               done

Теперь нам надо внести в настройки системы необходимость автоматического запуска этой службы. Но об этом позже. Вообще-то есть еще альтернатива. Можно внести вызов spam-php в скрипт демона nginx и туда же /usr/bin/php-cgi. Это позволит нам одной командой выключать и включать оба сервера сразу и не надо создавать обертку. Но мне только сейчас пришла в голову эта идея. Поэтому можете реализовать ее самостоятельно.
Давайте перейдем к настройке nginx. Откроем конфигурационный файл /etc/nginx/nginx.conf и внесем туда настройки двух виртуальных хостов.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log;
 
events {
    worker_connections  1024;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    tcp_nopush     on;
    keepalive_timeout  65;
 
     server {
	listen      80;
	server_name  localhost;
        charset utf-8;
 
        access_log  /var/log/nginx/host.access.log;
 
        location / {
            root   /srv/www/htdocs/;
            index  index.html index.htm;
        }
 
        #error_page  404              /404.html;
 
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /srv/www/htdocs/;
        }
    }
 
    # another virtual host using mix of IP-, name-, and port-based configuration  
    server {
        listen       nginx.test:80;
        server_name  nginx.test;
        charset utf-8;
 
        location / {
            root   /home/izumeroot/sites/nginx.test/;
            index  index.html index.htm index.php;
        }
 
	location ~ \.php$ {
            fastcgi_pass   127.0.0.1:1026;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/izumeroot/sites/nginx.test$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
 
    server {
        listen       nginx2.test:80;
        server_name  nginx2.test;
        charset utf-8;
 
        location / {
            root   /home/izumeroot/sites/nginx2.test/;
            index  index.html index.htm index.php;
        }
 
	location ~ \.php$ {
            fastcgi_pass   127.0.0.1:1026;
            fastcgi_index  index.php;
 
 
            fastcgi_param  SCRIPT_FILENAME  /home/izumeroot/sites/nginx2.test$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}

В строке fastcgi_pass 127.0.0.1:1026 прописан тот самый порт, о котором говорилось выше. Секции server содержат настройки виртуальных хостов. Первая для дефолтного, а вторые две для nginx.test и nginx2.test с файлами, которые находятся в /home/izumeroot/sites/nginx.test/ и /home/izumeroot/sites/nginx2.test/. Только для локальной машины надо прописать эти доменные имена также и в /etc/hosts.
Nginx имеет еще массу настроек, о которых можно прочитать на официальном сайте.
А теперь об автозапуске служб. Для их автозапуска нам необходимо создать символические ссылки в определенных каталогах. В openSUSE, правда, есть GUI для этого.

ln -s /etc/init.d/nginx /etc/init,d/rc3.d/S13nginx
ln -s /etc/init.d/spawn-php-demon /etc/init,d/rc3.d/S12spawnphp

Вот и все. Теперь можно поместить в папки /home/izumeroot/sites/nginx.test/ и /home/izumeroot/sites/nginx2.test/ тестовые php-скрипты с любимыми Hello World и phpinfo() и вызывать в браузере nginx.test и nginx2.test. У меня на nginx2.test локально прекрасно работает WordPress!
Жду информации о ваших успехах. На этом мы НЕ заканчиваем разговор о Nginx. Так что, если не хотите пропустить очередную статью, подпишитесь на новые сообщения блога.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong Rambler Закладки
Tags: ,

5 Responses to “Запускаем Php-сайт под Nginx”

  1.  Игорь Тельменко Says:

    Теперь и данный сайт работает на Nginx. Вчера настроил его на своем VDS. Может быть для каких-то экспериментов время от времени буду использовать Apache. Сейчас тестирую все функции своего блога. Если кто-нибудь заметит проблему - пишите.
    Спасибо!

  2.  debian-world Says:

    Пример запуска php + nginx под Debian: Настройка nginx с поддержкой PHP

  3.  lion Says:

    Я настроил связку NGinx как Фронтенд для Apache2, стало всё летать … но SMF 2.0 не может получить адрес с которого зашли, слышал что SMF работает на NGinx - хочу попробовать запустить часть сайтов под NGINX а часть под Apache2->NGinx

  4.  Manager Says:

    lion: Ну и как SMF без апачи на NGinx работает?
    У меня к SMF еще движок блогов и википедия прикручена, стоит ли ставить просто NGinx или все же лучше в связке с Apache?
    Вопрос актуальный, очень жду ответа в ближайшее время

  5.  lion Says:

    Всё работает, доказательство на 1clinux.org там же описание как я это делал:
    http://1clinux.org/index.php?topic=532.0

Leave a Reply

Для вставки кода используйте кнопку Код, по умолчанию используется синтаксис подсветки языка php, вы можете поменять его на любой другой поддерживаемый.