Что не так в моей конфигурации php-fpm?

8

У меня 64-битный сервер, но только 256 МБ оперативной памяти. Итак, я перешел на сервер nginx с fast-cgi для подключения к PHP. У меня работает PHP 5.3.6.

Проблема в том, что через каждые два или три дня, когда я пытаюсь получить доступ к любой странице PHP, я получаю внутреннюю ошибку сервера. Единственный выход - перезапустить php-fpm вручную. Это означает, что я должен был установить некоторые неправильные параметры, которые вызывают его удушье. Ниже я перечислил соответствующие конфиги.

/etc/php-fpm.conf: -

include=/etc/php-fpm.d/*.conf
log_level = error
;emergency_restart_threshold = 0
;emergency_restart_interval = 0
;process_control_timeout = 0

/etc/php-fpm.d/www.conf: -

[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

/etc/nginx/php.conf: -

location ~ \.php {
        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;

        fastcgi_pass unix:---some-location---;
}

Обновление 1

И у меня работает четыре процесса nginx. В среднем каждый процесс php-fpm занимает 35 МБ ОЗУ (размер виртуальной памяти 320 МБ каждый). У меня также запущен процесс MySql.

Обновление 2

Я забыл вставить журналы.

Журнал ошибок php-fpm: -

WARNING: [pool www] seems busy (you may need to increase start_servers, or min/max_spare_servers), spawning 8 children, there are 1 idle, and 7 total children
WARNING: [pool www] server reached max_children setting (10), consider raising it
NOTICE: Terminating ...

php-fpm www.error log: -

PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
AppleGrew
источник

Ответы:

17

Необоснованной рекомендацией было бы снизить ваши установленные значения - возможно, сократить их пополам.

У вас есть: pm.max_children = 10 Если вы говорите 35MB / process = 350MB; на 256-мегабайтном блоке это означает либо много обмена, либо нехватку памяти - ни то, ни другое.

Я бы сказал, что по крайней мере, 100 МБ для других процессов, может быть, даже 150 МБ, чтобы быть в безопасности, а затем разделить это число на 35 МБ, чтобы получить max_children. Оставьте все остальные числа в строке:

pm = dynamic
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500

Остановите PHP-FPM и запустите, freeчтобы получить представление о доступной памяти - разделите на свои 35 МБ, чтобы получить max_children.

В зависимости от того, сколько памяти занимает MySQL, вам может потребоваться сбросить max_children до 3.

Я обнаружил, что процессы PHP-FPM занимают много памяти, проведу быстрый эксперимент, чтобы определить, сколько реально используется. Остановите PHP-FPM и запустите free. Запустите PHP-FPM, посетите несколько общих страниц (необходимо, поскольку память увеличивается в зависимости от загруженных страниц) и проверьте общий объем используемой памяти, снова используя free- разделите разницу на количество процессов. Это не идеальная система, но я нахожу ее достаточно точной (иногда столбец данных в верхней части тоже неплох).

cyberx86
источник
Я делаю остановку freeи начинаю. Я делю эту свободную память на 35, чтобы получить max_children value. Я не понял цель последнего параграфа.
AppleGrew
Кажется, я могу поддерживать только максимум 2.3 процессов PHP. : P Во всяком случае у меня сейчас max_children3.
AppleGrew
а) Цель «последнего параграфа» состояла в том, чтобы получить более точное значение того, сколько потребляет процесс PHP. Я считаю, что значение из ps или top не всегда соответствует падению доступной памяти. Если вы найдете доступную память, запустите несколько процессов PHP, а затем заново измерите доступную память (вместо того, чтобы смотреть на память, используемую процессами), вы можете получить «альтернативное» (и, возможно, лучшее) значение для того, сколько памяти использует каждый процесс. б) Параметр memory_limit, предложенный invarbrass, также является хорошим предложением. c) Взгляните на скрипт mysqltuner.pl, он может помочь с вашей конфигурацией БД.
cyberx86
@ cyberx86, какое значение freeвы принимаете во внимание? Тот из строки '- / + buffers / cache', который используется для дискового кэша, но на самом деле бесплатный для приложений?
Роман Ньюаза
@RomanNewaza - да, вы хотите посмотреть на объем памяти, доступной для приложения, поэтому вы будете использовать запись 'free' в '- / + buffers / cache'.
cyberx86 13.12.12
6

Ваша настройка php-fpm выглядит нормально.

Но сервер, на котором вы работаете, несколько ограничен в ресурсах. Из журналов видно, что процессы PHP исчерпывают доступную память.

Добавление к предложениям, предоставленным Cyberx86:

Вы можете попробовать отредактировать параметр memory_limit в файле php.ini (см. Здесь ) (хотя я не уверен, что это принесет много пользы)

Учитывая небольшой объем системной памяти, я думаю, вам стоит серьезно подумать о переходе на 32-битную ОС. Использование ОС x64 на самом деле приносит вам больше вреда, чем приносит пользу.

Если вы не используете хранилище InnoDB в своей базе данных MySql, вы можете также рассмотреть возможность отключения InnoDB в вашем my.cnf - это сэкономит еще 100 МБ ОЗУ.

В Lowendbox есть отличное руководство по оптимизации серверов для конфигурации с низким объемом памяти.

invarbrass
источник
Ну, мой голос охрип, пытаясь убедить мою хостинговую компанию предоставить мне 32-битную ОС. Кажется, что по всей сети эти компании предоставляют только 64-битные. Я нашел только одну компанию, которая предоставляет 32-битные ОС, но они намного дороже.
AppleGrew
3

Очень удобная команда для поиска памяти, занятой php:

ps --no-headers -o "rss,cmd" -C php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

Затем вы разделяете оперативную память, которую хотите выделить для php, и у вас есть значение max_children!

Кроме того, вы можете контролировать вручную (необходимо настроить php-статус конечной точки) или с помощью Nagios.

Томас Деко
источник
awk: fatal: division by zero attempted
Самайо
1
Означает, что у вас нет процесса php5-fpm .... вам нужно изменить название процесса "php5-fpm", чтобы оно соответствовало вашему.
Томас Деко
Я использовал эту команду. ps --no-headers -o "rss,cmd" | grep php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'Как-то опции -C не работают.
августа
Попробуйте запустить команду отдельно (я имею в виду ps --no-headers -o "rss, cmd" сначала и т. Д.), Это должно быть легко отладить
Thomas Decaux