Сегодня мы затронем такую интересную тему как повышение скорости работы вашего сайта. Конечно же это и оптимизированный код и оптимизированные sql-запросы. Но есть и еще несколько мест, в которых производительность может падать. Одним из таких мест является http-сервер Apache. Есть целый ряд трюков, которые позволяют повысить пропускную способность этого узкого места. Один из таких трюков - установка вместо Apache более легковесного сервера. Одним из интересных решений может быть использование вместо Apache сервера Nginx, который разрабатывается Игорем Сысоевым.
Этот веб-сервер обладает немалыми возможностями. С полным их списком вы можете ознакомиться на официальном сайте. В данной статье пойдет речь о том как использовать вместо Apache этот замечательный сервер. Если ваш сервер на базе FreeBSD, то вот замечательная инструкция по установке Nginx в связке с php.
А наша статья конечно же для тех у кого Linux. Традиционно пример на основе openSUSE. Если у вас есть положительный или отрицательный опыт по данной теме с другими дистрибутивами, то напишите обязательно об этом в комментариях.
Итак начнем. Основная проблема в том, что у Nginx нет модуля mod_php. Однако он поддерживает технологию FastCGI для работы с внешними серверами и утилитами. PHP также поддерживает FastCGI и может быть использован для обработки FastCGI-запросов от nginx.
Существует 2 подхода
- Запуск встроенного в php сервера fastCGI
- Запуск 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. Так что, если не хотите пропустить очередную статью, подпишитесь на новые сообщения блога.
Теперь и данный сайт работает на Nginx. Вчера настроил его на своем VDS. Может быть для каких-то экспериментов время от времени буду использовать Apache. Сейчас тестирую все функции своего блога. Если кто-нибудь заметит проблему - пишите.
Спасибо!
Пример запуска php + nginx под Debian: Настройка nginx с поддержкой PHP
Я настроил связку NGinx как Фронтенд для Apache2, стало всё летать … но SMF 2.0 не может получить адрес с которого зашли, слышал что SMF работает на NGinx - хочу попробовать запустить часть сайтов под NGINX а часть под Apache2->NGinx
lion: Ну и как SMF без апачи на NGinx работает?
У меня к SMF еще движок блогов и википедия прикручена, стоит ли ставить просто NGinx или все же лучше в связке с Apache?
Вопрос актуальный, очень жду ответа в ближайшее время
Всё работает, доказательство на 1clinux.org там же описание как я это делал:
https://1clinux.org/index.php?topic=532.0