Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> WWW —> Nginx+php+fcgi

Nginx + PHP + Spawn-fcgi

Автор: RageLT.


Сейчас многие отказываются от apache в пользу nginx. Который, на мой взгляд, подкупает своей в первую очередь производительностью, возможностью быстрого и лёгкого масштабирования бекэндов в виде php серверов, так же расширенными возможностями конфигурации сервиса. Каждый может максимально точно подогнать его под себя.

Разберём два варианта установки, один из портов, второй из исходников. Каждый выберет себе подходящий.
И так, давайте приступим. (FreeBSD 6.2-RELEASE)

У С Т А Н О В К А   И З   П О Р Т О В

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

в конфигурации выбираем следующие пункты:
[X] HTTP_MODULE
[X] HTTP_PERL_MODULE
[X] HTTP_REWRITE_MODULE
[X] HTTP_STATUS_MODULE

php
cd /usr/ports/lang/php5
make install clean

в конфигурации выбираем нужные вам опции и обязательно:
[X] CLI        Build CLI version                                
[X] CGI        Build CGI version                                              
[X] REDIRECT   Enable force-cgi-redirect support (CGI only)    
[X] DISCARD    Enable discard-path support (CGI only)          
[X] FASTCGI    Enable fastcgi support (CGI only)                
[X] PATHINFO   Enable path-info-check support (CGI only)  

lighttpd
cd /usr/ports/www/lighttpd

Выполняем только
make

В конфигурационном меню убираем все опции.
После окончания компиляции делаем следующие:
cp work/lighttpd-1.4.18/src/spawn-fcgi /usr/local/bin/spawn-fcgi
cp work/lighttpd-1.4.18/doc/spawn-php.sh /usr/local/etc/rc.d/

слегка подредактируем /usr/local/etc/rc.d/spawn-php.sh
#!/usr/local/bin/bash
## ABSOLUTE path to the spawn-fcgi binary
SPAWNFCGI="/usr/local/bin/spawn-fcgi"
## ABSOLUTE path to the PHP binary
FCGIPROGRAM="/usr/local/bin/php-cgi"
## if this script is run as root, switch to the following user
USERID=nobody
GROUPID=nogroup 

Создадим тестовый php файл index.php
cat > /usr/local/www/nginx/index.php
<? phpinfo(); ?>
ctrl+d

Отредактируем конфигурационный файл nginx:
/usr/local/etc/nginx/nginx.conf
user  nobody;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   /usr/local/www/nginx;
            index  index.php;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:1026;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/www/nginx$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}

Вот и всё, можно взлетать:
/usr/local/etc/rc.d/spawn-php.sh
/usr/local/etc/rc.d/nginx start

.

У С Т А Н О В К А   И З   И С Х О Д Н И К О В

Сборку провожу в /usr/local/src/

Скачиваем и разжимаем nginx (0.6.14)
wget http://www.sysoev.ru/nginx/nginx-LAST.tar.gz
tar -zxf nginx-LAST.tar.gz
ln –s nginx-LAST nginx

Устанавливаем Perl Compatible Regular Expressions (на данный момент доступна версия 7.4)
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-LAST.tar.gz
tar -zxf pcre-LAST.tar.gz
ln –s pcre-LAST pcre

Удалим не нужные нам модули для реализации простого веб-сервера с поддержкой php.
cd nginx

./configure  --prefix=/usr/local/nginx \
--with-http_stub_status_module \
--without-http_empty_gif_module \
--without-select_module \
--without-poll_module \
--without-http_userid_module \
--without-http_auth_basic_module \
--without-http_autoindex_module \
--without-http_map_module \
--without-http_referer_module \
--without-http_proxy_module \
--with-pcre=../pcre

make && make install

Далее очередь php (5.2.4)
wget http://www.php.net/get/php-LAST.tar.gz/from/uk.php.net/mirror
tar -zxf php-LAST.tar.gz
ln –s php-LAST php

сd php

./configure \
--enable-fastcgi \
--enable-force-cgi-redirect \
--enable-discard-path

make && make intsall

Для запуска php я использую spawn-fcgi от lighttpd, на данный момент доступна 1.4.18. Так что пройдём к следующему шагу.
cd ..
wget http://www.lighttpd.net/download/lighttpd-LAST.tar.gz
tar -zxf lighttpd-LAST.tar.gz
cd lighttpd-LAST
./configure

make

make install нам не требуется, так как нам потребуются только два файла из данного проекта.
cp src/spawn-fcgi /usr/local/bin/spawn-fcgi
cp doc/spawn-php.sh /usr/local/etc/rc.d/

слегка подредактируем /usr/local/etc/rc.d/spawn-php.sh
#!/usr/local/bin/bash
## ABSOLUTE path to the spawn-fcgi binary
SPAWNFCGI="/usr/local/bin/spawn-fcgi"
## ABSOLUTE path to the PHP binary
FCGIPROGRAM="/usr/local/bin/php-cgi"
## if this script is run as root, switch to the following user
USERID=nobody
GROUPID=nogroup 

создаём запускной файл для nginx
touch /usr/local/etc/rc.d/nginx.sh

следующего содержания:
#!/bin/sh
nginx_enable=${nginx_enable-"NO"}
nginx_flags=${nginx_flags-""}
nginx_pidfile=${nginx_pidfile-"/usr/local/nginx/logs/nginx.pid"}

. /etc/rc.subr

name="nginx"
rcvar=`set_rcvar`
command="/usr/local/nginx/sbin/nginx"
load_rc_config $name
pidfile="${nginx_pidfile}"
extra_commands="configtest reload"
configtest_cmd="configtest_cmd"
configtest_cmd()  {
        echo "Configuration syntax test for ${name}."
        if ${command} ${nginx_flags} -t; then
                :
        else
                err 8 "FATAL: bad config for ${name}"
        fi
}
start_cmd="echo \"Starting ${name}.\"; 
/usr/bin/limits -U www ${command} ${nginx_flags}"
run_rc_command "$1"

не забываем прописать в /etc/rc.conf
nginx_enable="YES"

Конфигурационный файл для nginx
/usr/local/nginx/conf/nginx.conf
user  nobody;
worker_processes  1;
pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
    server_names_hash_max_size 2048;
    server_names_hash_bucket_size 128;
    server {
        listen       80;
        server_name  yoursite.com;
        charset utf8;
        location / {
            root   /path/yoursite.com;
            index  index.html index.php;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:1026;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /path/yoursite.com$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
}

Вот собственно и всё. Пробуем стартануть.
/usr/local/etc/rc.d/spawn-php.sh
/usr/local/etc/rc.d/nginx.sh

*****
П.С. В этой статье описывается конфигурация с учётом того, что все приложения будут установлены на одном сервере. Если кому-то интересно, то могу написать продолжение в котором разберём конфигурацию с учетом того, что php будет стоять на других серверах как backend, а мы будем балансировать нагрузку на них с помощью nginx.



размещено: 2007-10-22,
последнее обновление: 2007-10-23,
автор: RageLT


Valera, 2007-10-23 в 1:21:18

То что в ПС интересует :)

Wizard, 2007-10-23 в 4:51:45

Вобщем настройка под дешовинький, непосещаемый сайт :) максимум 1000 посетителей потянет, вобшем НЕ ЗАЧЕТ

A. Salnikov, 2007-10-23 в 6:16:28

Познавательно. Ждём продолжения

www2, 2007-10-23 в 7:40:03

ИМХО именно apache и есть самый конфигурируемый сервер. А все веб-сервера, которые быстрее работают, явно включают в себя меньше возможностей, в т.ч. и по настройке.

wizard, 2007-10-23 в 8:21:26

Если допустим один или несколько серверов обслуживают одни сайт, то особой извращенной конфигурации и не требуеться, поэтому такие сервера как нжинайкс и лайти , тут очень хорошо справляються

Fox, 2007-10-23 в 9:00:05

а меня очень интересует разборка настройки распределенной сбалансированной архитектуры! так что я жду продолжения :)

lissyara, 2007-10-23 в 9:12:19

Заплевали, заплевали :)))
==========
2 Wizard
1000 в секунду, в минуту, в час? Уточните - а то не в тему получается замечание. Плюс обоснуйте свою точку зрения - иначе - голословный крик и незачёт вам.
2 www2
Могу привести типичный для нашей страны пример когда нужен именно нгинкс - например сайт с региональной ориентированностью. И половина посетителей на модемах.
И несчастный апач, весом в 20 мегов пытающийся запихать в модемный канал картинку 1x1 пиксел... И так по треду на каждую картинку. А канал тоненький у клиента.
================
от себя тоже кину камень - не из портов собрано - не BSD-стиль :) После увольнения автора системы её проще снести чем поддерживать. Плюс при сборке не везде указывались префиксы - подозреваю, загадилась сама система - тоже минус.
Посему - пожелание к продолжению - сделать из портов.
А сама статья - мне понравилась.

Wizard, 2007-10-23 в 9:20:30

liss, ну даже если взглянуть на вот эти переменные
worker_processes  1;
pid        logs/nginx.pid;
events {
   worker_connections  1024;
}

то могу сказать по личному опыты, нстройки очень высоканагруженных проектов, то это максимум 300 пользователей в  online. да и вообще это дефолтный конфиг, его всегда пиходиться переписывать под конкретные сайты, почти с нуля

RageLT, 2007-10-23 в 9:36:01

2 Wizard, тут предоставлена стандартная конфигурация, без какой-либо оптимизации, так как это отдельная тема для разговора. Скажем так, это заметка, как завести машину.
2 www2, о да, в апаче столько говно настроек, что и не знаешь куда их применить =).
2 lissyara, камень я поймал по поводу портов (хотя в статье порты описаны), постараюсь придерживаться устоям данного сайта=)

kmb, 2007-10-23 в 10:32:53

2lissyara
"Посему - пожелание к продолжению - сделать из портов."
Вот так хотелось бы: "Посему - пожелание к продолжению - сделать ВСЁ из портов."
2RageLT

"...постараюсь придерживаться устоям данного сайта"
Как точно замечено ;) Еще не видя комментариев, удивился, как Лис пропустил данную статью %)
А так спасибо за статью, всё больше и больше хочеться попробывать этот nginx =)

lissyara, 2007-10-23 в 10:36:30

Ну, было долгое обсуждение в почте. Ну а почему - именно потому, что у кого-то возникнет желание сделать тоже самое из портов. А значит рано или поздно будет и про порты статья :)

RageLT, 2007-10-23 в 13:57:15

Посыпал голову пеплом, достал бубен и пересобрал всё исключительно из портов. =)
Получилось два варианта, один из портов, второй из исходников. Каждый выберет себе подходящий.

top, 2007-10-23 в 23:04:26

хех когда свою заметку об энжниксе писал этой статьи не видел.. но неплохая выхла

Peter, 2007-10-24 в 14:29:15

Хочется узнать: а для perl-fastcgi что-нибудь подобное уже написано, али самому взяться?

Great.Megatron, 2007-10-24 в 22:26:15

Небольшое предложение: более гибкая (в смысле rc.d, а не в смысле конфигурации) замена spawn-php.sh (только для *BSD). Позволяет делать корректный (более-менее) старт/стоп. Можно модифицировать для произвольного fcgi-сервера.

#!/bin/sh
# Define these fcgiphp_* variables in one of these files:
#       /etc/rc.conf
#       /etc/rc.conf.local
#
# DO NOT CHANGE THESE DEFAULT VALUES HERE
#
fcgiphp_enable=${fcgiphp_enable-"NO"}
fcgiphp_flags=${fcgiphp_flags-"-s /tmp/php-fcgi.sock -u www -g www"}

. /etc/rc.subr

name="fcgiphp"
rcvar=`set_rcvar`
command="/usr/local/bin/spawn-fcgi"
fcgi_server="/usr/local/bin/php-cgi"
fcgi_server_short="php-cgi"

load_rc_config $name

start_cmd="echo \"Starting ${name}.\"; ${command} -f ${fcgi_server} ${fcgiphp_flags}"
stop_cmd="echo \"Stopping ${name}.\"; while [ 1 ]; do killall ${fcgi_server_short} || break; done"

run_rc_command "$1"

zik, 2007-10-25 в 22:24:17

П.С. В этой статье описывается конфигурация с учётом того, что все приложения будут установлены на одном сервере. Если кому-то интересно, то могу написать продолжение в котором разберём конфигурацию с учетом того, что php будет стоять на других серверах как backend, а мы будем балансировать нагрузку на них с помощью nginx.

Да, мне б это было очень интересно ! Спасибо за статью =)

Great.Megatron, 2007-10-30 в 20:53:20

Извините, если сказал грубость, но RTFM:
http://wiki.codemongers.com/NginxLoadBalanceExample

rayne, 2007-11-02 в 22:46:48

пробовал собирать по доке четко по шагово
#/usr/local/etc/rc.d/spawn-php.sh

/usr/local/etc/rc.d/spawn-php.sh: ${!i}: Bad substitution
Собирал по доке по документации с
blog.kovyrin.net там таже фигня получилась .
Почему оно ругается ?

alvelcom, 2007-11-04 в 16:45:34

Товарищщи! у меня вопрос конечно не совсем в тему, но всёже.
я слышал про ограничение на 65536 открытых портов
вопрос: это ограничение на всю систему или на одну карточку?

вопрос II: а через юникс-сокет можно?

www2, 2007-12-05 в 10:02:02

Вот сказал я правду о apache и все сразу на меня ополчились. Хочу сказать, что я сам не поклонник apache и использую lighttpd. Хотелось бы вот только для него увидеть что-нибудь вроде mod_perl ну или хотя-бы perl-fastcgi...

netcat, 2007-12-12 в 20:16:42

nginx, это на котором пол-рунета лежит в 502 Gateway Timeout ? :)

lissyara, 2007-12-12 в 20:52:30

Ещё один...
Товарищи, вы хоть не позорьтесь рассуждая о том чего не знаете...
Эта ошибка означает что упало приложение за нгинксом, которое он собсно и проксировал... Апач например...
А если нгинкс падает - то вы ничего не увидите. Коннекшен рефьюзед и всё...

wed, 2007-12-14 в 9:45:47

2raune:
пишите bash /usr/local/etc/rc.d/spawn-php.sh
а вообще используйте предложение Great.Megatron

netcat, 2007-12-14 в 20:04:56

Ну да, просто почему это случается чаще всего с nginx ?  Кто сказал, что nginx упал ? Я такого не говорил. Может с другой стороны посмотреть на проблему ?:)

lissyara, 2007-12-14 в 20:14:03

Потому что его не ставят на сервер с одним посетитем в час.
А на высоко нагруженном сервере - падение происходит чаще ччем на том, который ничё не делает.
=========
а фраза "на котором" - может быть понята иначе? :)

netcat, 2007-12-15 в 10:21:50

Мну не увидел фразы "на котором" :) Наверное плохо смотрел. Лис, я вот вижу факты. 502 Gateway Timeout вижу пожалуй только на nginx. Apache встречал, но очень давно. Или ты хочешь сказать, что все юзают nginx как прокси ?;)

netcat, 2007-12-15 в 10:26:58

И между прочим мну знает, что такое mod_proxy :)

lissyara, 2007-12-15 в 12:18:54

Да. Конфигурация рассмотренная в статье - черезвычайно редкий случай.
>nginx, это на котором пол-рунета лежит в 502 Gateway Timeout ? :)
вопросы?

netcat, 2007-12-15 в 12:23:37

Я не спорю со знаниями и опытом автора. Я про nginx вообще-то речь веду. Какие могут быть вопросы, ибо это так - 502 - nginx :)

netcat, 2007-12-15 в 12:26:42

Хорошо, "на котором" показал :) Ну и ? да, именно на нем, и никто тут не говорил что "он", не правда ли ?:)

netcat, 2007-12-15 в 12:28:18

А то, что его модуль mod_proxy - это уже стоит задуматься :)

lissyara, 2007-12-15 в 12:30:29

Предлагаю перенести в форум пустое обсуждение.

alvelcom, 2007-12-15 в 20:06:45

1)суть в том что, apache для каждого соединения
использует кучу мегабайт. это раз.
второе это, то что при этом медленнее работает.
в отличие от nginx, который мало весит в памяти
и работает пошустрее
вот админы и придумали прицыпить их вместе.
nginx часто не используют, потому что он CGI не берёт.

2) mod_proxy - надо переименовть
в mod_tormoz или в mod_very_tormoz

3) 502 - это apache!
возникает, когда nginx не может подрубится к apache, т.е. когда он перегружен( он - apache )

Igorek, 2008-01-25 в 9:26:37

Вот если бы под nginx, был написан mod_wsgi, цены б ему не было

cam, 2008-01-29 в 16:28:47

Очень познавательно. Ну а где обещанное продолжение?
//П.С. В этой статье описывается конфигурация с учётом того, что все приложения будут установлены на одном сервере. Если кому-то интересно, то могу написать продолжение в котором разберём конфигурацию с учетом того, что php будет стоять на других серверах как backend, а мы будем балансировать нагрузку на них с помощью nginx.

anight, 2008-02-08 в 13:15:54

[X] REDIRECT   Enable force-cgi-redirect support (CGI only)
[X] DISCARD    Enable discard-path support (CGI only)
[X] PATHINFO   Enable path-info-check support (CGI only)

Эти опции не имеют к fastcgi никакого отношения. Автору бы почитать сначала что к чему.

junqed, 2008-03-22 в 19:45:54

Можно в nginx.conf поставить обработку 500-х ошибок - и создать файл покрасивее (например, уважаемый посетитель, зайди позже, бэкэнд упал) - тогда лучше будет, и все наконец полюбят nginx :)

nikll, 2008-04-15 в 14:51:40

Есть вариант вместо spawn-cgi использовать более внятный скрипт для запуска pgp-cgi:
[code]
#!/bin/sh
#

# PROVIDE: php_fastcgi
# REQUIRE: DAEMON
# BEFORE:  LOGIN
# KEYWORD: shutdown

. /etc/rc.subr

name="php_fastcgi"
rcvar=`set_rcvar`

load_rc_config $name

: ${php_fastcgi_enable="NO"}
: ${php_fastcgi_user="www"}
: ${php_fastcgi_bindaddr="127.0.0.1"}
: ${php_fastcgi_bindport="9000"}
: ${php_fastcgi_children="5"}
: ${php_fastcgi_max_requests="1000"}
: ${php_fastcgi_allowed_env=""}

export PHP_FCGI_CHILDREN=${php_fastcgi_children};
export PHP_FCGI_MAX_REQUESTS=${php_fastcgi_max_requests};

command="/usr/local/bin/php-cgi";
command_args="-q -b ${php_fastcgi_bindaddr}:${php_fastcgi_bindport} &";
pidfile="/var/run/${name}.pid";

_allowed_env="ORACLE_HOME PATH USER PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS";
_allowed_env="${_allowed_env} ${php_fastcgi_allowed_env}";

start_precmd="${name}_start_precmd";
start_postcmd="ps -U ${php_fastcgi_user} -o 'pid,command'|grep ${command}|head -1|awk — '{print \$1}' > ${pidfile}";

php_fastcgi_start_precmd()
{
   export USER=${php_fastcgi_user};
   E=
   for i in ${_allowed_env}; do
       eval _val="\$$i";
       if [ "${_val}_x" != "_x" ]; then
           eval _add="$i=$_val";
           E="${E} ${_add}";
       fi
   done
   command="env - ${E} ${command}";
}

load_rc_config $name;

run_rc_command "$1";
[/code]

в /etc/rc.conf добовляем:
[code]
nginx_enable="YES"
php_fastcgi_enable="YES"
php_fastcgi_user="www"
php_fastcgi_bindaddr="127.0.0.1"
php_fastcgi_bindport="7000"
hp_fastcgi_children="5"
php_fastcgi_max_requests="1000"
php_fastcgi_allowed_env=""
[/code]

Aris, 2008-04-24 в 12:47:23

П.С. В этой статье описывается конфигурация с учётом того, что все приложения будут установлены на одном сервере. Если кому-то интересно, то могу написать продолжение в котором разберём конфигурацию с учетом того, что php будет стоять на других серверах как backend, а мы будем балансировать нагрузку на них с помощью nginx.

Автор. Было бы очень интересно увидеть продолжение.

beee, 2008-06-10 в 4:04:04

Использую nginx для API, Spawn-CGI + eAccelerator nginx  с ошибкой 502 как минимум раз в день падает

shelma, 2008-07-30 в 22:06:02

поправка стартового скрипта для семерки, дабы заработало.
spawn-php.sh:
........
. /etc/rc.subr

name="fcgiphp"
rcvar=${name}_enable

fcgiphp_enable=${fcgiphp_enable-"NO"}
fcgiphp_flags=${fcgiphp_flags-"-s /tmp/php-fcgi.sock -u www -g www"}
.........

олплпр, 2008-08-23 в 20:25:41


Товарищи!

Это поля для ввода комментариев к статье, а не для вопросов. Сюда пишите найденные баги, или какие-то фичи :)


Для вопросов есть форум!

Vladimir, 2008-08-30 в 23:49:42

Чуваки спасибо вам за всеобъем!
Всеработает супер!
Памяти стало уе*****я.
И спасибо nikll за запуск fastcgi без spawn-fcgi!

dikens3, 2008-11-27 в 16:59:37

Спасибо nikll за скрипт, я его подправил, т.к. он не удалял pid-файл и не создавал и загрузке сервера.


#!/bin/sh
#
# PROVIDE: php_fastcgi
# REQUIRE: DAEMON
# BEFORE:  LOGIN
# KEYWORD: shutdown

. /etc/rc.subr

name="php_fastcgi"
rcvar=`set_rcvar`

load_rc_config $name

: ${php_fastcgi_enable="NO"}
: ${php_fastcgi_user="www"}
: ${php_fastcgi_bindaddr="127.0.0.1"}
: ${php_fastcgi_bindport="9000"}
: ${php_fastcgi_children="5"}
: ${php_fastcgi_max_requests="1000"}
: ${php_fastcgi_allowed_env=""}

export PHP_FCGI_CHILDREN=${php_fastcgi_children};
export PHP_FCGI_MAX_REQUESTS=${php_fastcgi_max_requests};

command="/usr/local/bin/php-cgi";
command_args="-q -b ${php_fastcgi_bindaddr}:${php_fastcgi_bindport} &";
pidfile="/var/run/${name}.pid";

_allowed_env="ORACLE_HOME PATH USER PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS";
_allowed_env="${_allowed_env} ${php_fastcgi_allowed_env}";

start_precmd=start_precmd;
start_postcmd="sleep 1;ps -U ${php_fastcgi_user} -o 'pid,command'|grep ${command}|head -1|awk '{print \$1}' > ${pidfile}";
stop_postcmd=stop_postcmd;

start_precmd()
{
  export USER=${php_fastcgi_user};
  E=
  for i in ${_allowed_env}; do
      eval _val="\$$i";
      if [ "${_val}_x" != "_x" ]; then
          eval _add="$i=$_val";
          E="${E} ${_add}";
      fi
  done
  command="env - ${E} ${command}";
}

stop_postcmd()
{
   rm -f $pidfile
}

load_rc_config $name;

run_rc_command "$1";

Rustam, 2009-01-26 в 7:46:10

У меня nginx работал больше года.
Но в последнее время часто стала выскакивать 502 Default Gateway Timeout.
При этом нельзя сказать что бакенд перегружен.
Я не раз внимательно наблюдал как появляется эта ситуация.
1 - Появляется большое число запросов
2 - Растет загрузка процессора
3 - ПХП не справляется, запросы к базе выполняются по 200-300 секунд (не все запросы сумел почистить)
4 - Внезапно нагрузка резко падает, именно в этот момент nginx выдает 502 ошибку. (Иногда 503, при этом система ругается на очень большое число открытых файлов).
5 - В базе видно Sleep коннекты, которые отрубаются через 60 секунд (настройка мускула). Причем, сразу после этого появляются новые коннекты, и опять в состоянии Sleep.
6 - Перегрузка nginx не помогает, а вот перегрузка PHP сразу дает результат. Нагрузка на проц опять подскакивает до рабочей 60-70 %. И так до следующего раза.

Мои личные выводы:
1 - Виноват PHP (первая моя мысль). У меня стоит два бакенда на одной машине. Один поднял при помощи spawn другой при помощи самопального скрипта (по типу того что в статье). Сделал так специально чтобы посмотреть разницу.
Никакой разницы не увидел. Падают оба одновременно.
2 - То что они  одновременно падают, навело подозрения на мускул. Для проверки поставил еще один бакенд, на другую машину. Там другая Ось, другие настройки. В моменты падения сервера, этот бакенд тоже не отвечал.
3 - Поставил еще один мускул на другой сервер, и перевел на него часть сервисов своего сайта. Третий бакенд направил на новый мускул. Результат: В момент падения основного сервера, резервный работал как часы.

Итак.
1 - Основная система (FreeBSD 6.1 PAE i386 6 Gbt RAM, Intel Xeon 3 GHz)  ругается на большое число открытых файлов (в одной из баз мускула больше 5000 таблиц). Средняя нагрузка 60-70%, пиковая 98%. Время от времени (сразу после пиков) начинаются припадки, основные симптомы: резкое падение нагрузки на процессор, при этом все соединения PHP2MySQL висят но ничего не делают.
2 - Вторая система (Slackware ?? i386, 1 Gbt RAM, Intel Xeon 3 GHz), средняя нагрузка 10-15%, в пике 30%. Работает стабильно.

Мой вывод, виноват PHP-FCGI - до сих пор нет нормального управления сервисом. В момент пиковой нагрузки, начинают сыпаться ошибки и срабатывает PHP_FCGI_MAX_REQUESTS, который должен перезапускать дочерние процессы. Вот в этот момент и происходит припадок.
Проверял эту идею следующим образом.
Уменьшал значение PHP_FCGI_MAX_REQUESTS до 1000, потом увеличивал до 1000000.
Результат: при большом значении PHP_FCGI_MAX_REQUESTS система работала дольше (падения 2-3 раза в день), при PHP_FCGI_MAX_REQUESTS=1000 - падение каждые 20-30 минут.

lisergey, 2009-01-26 в 16:59:18

а пределы ядра (kernel limits) не смотрели?
например, у PostgreSQL есть четкая зависимость кол-ва одновременных коннектов от ряда переменных ядра, которые надо увеличивать от значений, стоящих по умолчанию (на мой взгляд весьма консервативных).

Rustam, 2009-01-27 в 7:06:45

Смотрел и конечно подправил. В частности количество одновременно открытых файлов для одного процесса увеличил в 10 раз.
Помогло.
Кстати, вчера сделал еще один эксперимент.
Увеличил количество дочерних процессов у ПХП до 50 (у каждого, в сумме получилось 100 процессов) со вчерашнего дня ни одного падения сервера не было.
Продолжаю наблюдения.

Rustam, 2009-01-30 в 8:03:46

Супер! За последние 2 суток только одно падение, и то по причине большой нагрузки (нагрузка процессора 100%). При это сам ПХП работал как трактор "Беларусь".
Вся проблема оказалась именно в малом числе процессов ПХП. Так же рекомендую выставлять большое значение PHP_FCGI_MAX_REQUESTS, у меня стоит 1000000.

junqed, 2009-02-10 в 22:53:45

Попробуйте патч для php php-fpm вместо PHP-FCGI. Читать тут - http://php-fpm.anight.org/

Лизард, 2009-03-21 в 11:46:16

Интересно, эта конфигурация сгодится для торрент-трекера с числом одновременных коннектов в 20-30 тысяч???

Тореро, 2009-04-07 в 10:53:49

Лизард, для вопросов - форум есть
но "раз пошла такая пьянка" (с) - для такого кол-ва коннектов нужна балансировка нагрузки между несколькими бекендами

arez, 2009-05-25 в 10:06:16

Когда добрался до строчки
cp work/lighttpd-1.4.18/src/spawn-fcgi /usr/local/bin/spawn-fcgi
cp work/lighttpd-1.4.18/doc/spawn-php.sh /usr/local/etc/rc.d/
, то обнаружил,что у меня uname -a
7.1-RELEASE-p5 FreeBSD
нет файла work/lighttpd-1.4.18/src/spawn-fcgi,
зато обнаружил порт
make search name=spawn-fcgi
Port:   spawn-fcgi-1.6.2_1
Path:   /usr/ports/www/spawn-fcgi
Info:   spawn-fcgi is used to spawn fastcgi applications
Maint:  genserg@hotmail.com
B-deps:
R-deps:
WWW:    http://www.lighttpd.net/

Отлично работает. Спасибо за статью.

risk94, 2010-09-11 в 17:43:54

ошипке:

Создадим тестовый php файл index.php

cat > /usr/local/www/nginx/index.php
<? phpinfo(); ?>
ctrl+d

надо:

<?php



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.0623 секунд
Из них PHP: 35%; SQL: 65%; Число SQL-запросов: 86 шт.
Исходный размер: 77469; Сжатая: 16636