php-fastcgi

У меня стоял Apache 2.2 и mod_php, так как Apache жрет не мало ресурсов, я решил постепенно переводить проекты на сервере на связку Nginx + PHP-FastCGI, а в качестве спаунера php-fpm.

Вкратце, что такое FastCGI и почему он лучше чем mod_php?

FastCGI это высокопроизводительный и масштабируемый интерфейс для взаимодействия web-сервера и приложений, дальнейшее развитие технологии CGI. Ознакомиться с более подробной информацией о FastCGI вы можете на официальном сайте или в Википедии.

Основное преимущество FastCGI в изолировании динамического языка от web-сервера. Например, запуск FastCGI процесса под пользователем, отличным от пользователя web-сервера, а также процесс может находиться в chroot'е, отличном от chroot'а web-сервера. Помимо всего прочего, эта технология позволяет запускать web-сервера и CGI процессы (теже php скрипты) на различных хостах, что улучшает масштабируемость и также способствует безопасности без существенной потери в производительности.

Ну а зачем нам php-fpm, если PHP и так поддерживает работу в режиме FastCGI?

php-fpm — это патч для PHP, для использования PHP как FastCGI процесса в высоконагруженных системах. Устраняет ряд проблем мешающих использовать PHP в режиме FastCGI. Андрей Нигматулин представил набор патчей php-fpm к PHP 4/5, устраняющих ряд проблем, которые мешают использовать PHP в режиме FastCGI на высоконагруженных системах.

Возможности php-fpm:

* Управление процессами. Возможность «плавно» останавливать и перезапускать php воркеры без потери запросов. Возможность плавно обновлять конфигурацию и binary без потери запросов;
* Ограничение ip адресов, с которых могут приходить запросы от web сервера;
* Динамическое количество процессов, в зависимости от нагрузки (TODO);
* Запуск воркеров с разными uid/gid/chroot/environment и разными php.ini опциями;
* Логирование stdout & stderr рабочих процессов;
* Аварийный перезапуск всех процессов при случайном разрушении shared memory opcode cache, если используется акселератор;
* Принудительное завершение подвисших процессов, если set_time_limit () не срабатывает (TODO);

http://php-fpm.org/wiki/What_is_PHP-FPM

Андрей Нигматулин / php-fpm / PHPConf 08 from Mihail Andreev on Vimeo.

Кстати, в видео я тоже поучаствовал, на 5-ой минуте и 20-ой секунде я там прохожу перед камерой в костюме и красной футболке... :D


Итак, приступим!

Установка Nginx

На самом деле Nginx у меня был уже установлен, но для полноты статьи я расскажу как и его установить. В зависимости от необходимого функционала, либо от стабильности версии, вам надо выбрать подходящую версию Nginx. Стабильная находится в каталоге «/usr/ports/www/nginx/», а более новая в «/usr/ports/www/nginx-devel/», у меня стоит именно вторая.

# cd /usr/ports/www/nginx-devel/
# make install clean

Всё, Nginx установлен, добавьте его в автозагрузку:

# echo 'nginx_enable="YES"' >> /etc/rc.conf

Установка php-fpm

Процесс заключается в пропатчивании и переустановки PHP интерпретатора с поддержкой FastCGI и php-fpm.

Установка из сорцов

Заходим на оф. сайт PHP и качаем необходимую версию PHP интерпретатора со страницы http://www.php.net/downloads.php, у меня это PHP 5.2.10.

# cd /tmp
# fetch http://ru2.php.net/get/php-5.2.10.tar.gz/from/ru.php.net/mirror

Заходим на оф. сайт проекта php-fpm, в раздел загрузок http://php-fpm.org/download и выбираем подходящую для вашего PHP интерпретатора версию патча. У меня это PHP 5.2.10, поэтому я буду ставить именно его.

# cd /tmp
# fetch http://php-fpm.org/downloads/php-5.2.10-fpm-0.5.13.diff.gz
# tar -xzf php-5.2.10.tar.gz
# gzip -cd php-5.2.10-fpm-0.5.13.diff.gz | patch -d php-5.2.10 -p1
# cd php-5.2.10
# ./configure --enable-fastcgi --enable-fpm
# make all install

Теперь, скопируем скрипт инициализации php-fpm в каталог «/usr/local/etc/rc.d» и назначим ему права на запуск:

# cp /tmp/php-5.2.10/sapi/cgi/fpm/php-fpm /usr/local/etc/rc.d/
# chmod +x /usr/local/etc/rc.d/php-fpm

Установка из портов

Тут все намного проще... :)

# cd /usr/ports/lang/
# fetch http://php-fpm.org/downloads/freebsd-port/php-5.2.10-fpm-0.5.13.tar.gz
# tar -xzvf php-5.2.10-fpm-0.5.13.tar.gz
# rm php-5.2.10-fpm-0.5.13.tar.gz
# cd php5-fpm
# make install

Завершение установки

После установки, проверьте версию php:

# php -v
PHP 5.2.10 (cli) (built: Sep  2 2009 12:46:58)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies

Если «built» сегодняшний, то всё оки, если нет — отпишите в комментарии, помогу разобраться.
Я ставил и из сорцов и из портов, так что все проверено на себе! :)

Добавим в автозагрузку:

# echo 'php_fpm_enable="YES"' >> /etc/rc.conf

Настройка Nginx

Теперь настраиваем Nginx, отредактируйте конфиг «/usr/local/etc/nginx/nginx.conf» или свой «vhost»:

server {

        listen 80;
        server_name demo.adw0rd.ru;

        location ~* \.(jpg|jpeg|gif|png|ico|css|zip|js|swf)$ {
                root /home/adw0rd/adw0rd.ru/demo;
        }

        location / {
            fastcgi_pass   82.146.63.195:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/adw0rd/adw0rd.ru/demo$fastcgi_script_name;
            include        fastcgi_params;
        }
}

Чуть более подробно о конфигурации nginx тут и тут.

Настройка php-fpm

Я покажу части конфига, которые только отличаются от «php-fpm.conf.default», весь конфиг можно взять тут.

<value name="listen_options">

        Set listen(2) backlog
        <value name="backlog">-1</value>

        Set permissions for unix socket, if one used.
        In Linux read/write permissions must be set in order to allow connections from web server.
        Many BSD-derrived systems allow connections regardless of permissions.
        <value name="owner">www</value>
        <value name="group">www</value>
        <value name="mode">0666</value>
</value>
...
Unix user of processes
<value name="user">www</value>

Unix group of processes
<value name="group">www</value>
...
Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect.
Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+)
Makes sense only with AF_INET listening socket.
<value name="allowed_clients">127.0.0.1,82.146.63.195</value>

«82.146.63.195» — это ип моего сервера, на котором крутится nginx. Ему то мы и разрешим доступ.

Запуск

Теперь осталось только запустить nginx и php-fpm:

/usr/local/etc/rc.d/nginx restart
/usr/local/etc/rc.d/php-fpm restart

Если не запустилось, то смотрите «/var/log/php-fpm.log». Если нету файла лога вообще, то создайте его и права на запись выставите.
Вот и все, в следующей статье расскажу о spawn-fcgi (раньше входил в lighttpd).


Комментарии (16) на запись «Nginx. Использование PHP в режиме FastCGI с помощью php-fpm»

» Трекбеки скрыты, показать их?
  1. Имя | 27.01.2010 в 18:21

    Блииин, че нету в пакетах nginx и php шоле?

  2. adw0rd | 27.01.2010 в 18:29

    Я не понял вопроса.

  3. ash2k | 27.01.2010 в 20:20

    Хай) Мы в последнее время используем spawn-fcgi - он есть в портах и с ним не надо патчить PHP и, соответственно, можно завести с любой версией. Конфиг nginx я обычно стараюсь писать как то так (с try_files):

    server {

    listen 80;

    server_name demo.adw0rd.ru;

    location / {

    root /home/adw0rd/adw0rd.ru/demo/public;

    expires 7d;

    try_files $uri @php;

    }

    location @php {

    expires off;

    fastcgi_pass 82.146.63.195:9000;

    fastcgi_param SCRIPT_FILENAME /home/adw0rd/adw0rd.ru/demo/index.php;

    include fastcgi_params;

    }

    }

    Плюсы:

    — не надо заморачиваться на расширения файлов. Можно указать expires и т.п.

    Минусы:

    — надо следить чтобы try_files не отдал .php как статику. Решается легко — в директории, указанной в root, не должно быть .php файлов. У меня обычно в проекте есть папка public где лежит только статика. Все .php файлы лежат в другом месте (см. конфиг выше). Вот :)

    Еще я обычно задаю SCRIPT_FILENAME жестко. Ну это от проекта конечно зависит.

  4. vasa_c | 27.01.2010 в 21:15

    Смысл то не в том же, что fastcgi много лучше модуля (в основной массе всем на chroot, других пользователей и другие хосты наплевать), а в том что апач прожорлив слишком, нужно от него избавляться.

  5. adw0rd | 28.01.2010 в 00:50

    ash2k, я под убунтой на работе юзаю spawn-fcgi, скоро и про него напишу. Думаю даже что он побыстрее должен быть... Надо бы его потестить с fpm

    Можно указать expires и т.п.

    Ну в моей конструкции тоже можно, я так и юзаю, но в примере не показал :)

    У меня обычно в проекте есть папка public где лежит только статика.

    У меня она называется «static» :)
  6. adw0rd | 28.01.2010 в 00:51

    vasa_c, ну а я о чем?)

  7. ash2k | 03.02.2010 в 15:52

    Жду когда php-fpm, вмерженная в PHP, стабилизируется и будет уже в релизе вместе с PHP идти. Вот тогда будет действительно клево. Ты ведь в курсе, что патч php-fpm приняли в основной реп PHP?

    p.s. а вообще мы тут планируем на Python перейти :) задолбал PHP костылями!

  8. ash2k | 03.02.2010 в 15:53

    у тебя кстати тут коменты глючили несколько дней назад — не смог сразу ответ написать. сейчас вот нормально с первого раза отправилось. тогда писало что-то типа «ничего не найдено» если я правильно помню.

  9. adw0rd | 03.02.2010 в 16:33

    ash2k, я не в курсе был что fpm патчи внесут в core. Ты кстати слышал о Facebook и перепатчиваниие PHP ими?

    Камменты глючили из-за того, что я переводил свой блог на fpm )

  10. adw0rd | 03.02.2010 в 16:35

    p.s. а вообще мы тут планируем на Python перейти :) задолбал PHP костылями!

    да, меня тоже достал PHP и я перешел на Python :) но по работе все еще приходится иметь дело с PHP, а также некоторые свои проекты на PHP поддерживаем/дорабатываем
  11. adw0rd | 03.02.2010 в 20:24

    А вот и про фейсбуковский HipHop rmcreative.ru/blog/post/hiphop

  12. ash2k | 03.02.2010 в 21:41

    да я читал про этот хипхоп. интересно что быстрее — написаное на пхп и «скомпиленное» этим хипхопом или напимер джава.

  13. adw0rd | 03.02.2010 в 22:33

    Думаю скоро бенчмарки появятся.

  14. sd | 20.02.2010 в 19:55

    # tar -xzf php-5.2.10.tgz

    Наверное, имелось ввиду:

    # tar -xzf php-5.2.10.tar.gz

  15. adw0rd | 20.02.2010 в 22:32

    Спасибо что заметили, исправил

  16. xapmc | 29.05.2010 в 23:46

    нужно в конфиге php-fpm.conf прописать

    Address to accept fastcgi requests on.

    Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket'

    х.х.х.х:9000

    где x.x.x.x ваш ip адрес

    Строка номер 41 Это типа на каком адресе слушать

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


служба эвакуации