Назад | Перейти на главную страницу

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

У меня 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

Рекомендуется снизить установленные значения - возможно, вдвое.

У вас есть: pm.max_children = 10 Если вы говорите 35 МБ / процесс = 350 МБ; на коробке с 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 - разделите разницу на количество процессов. Это не идеальная система, но я считаю ее довольно точной (иногда столбец данных вверху тоже неплох).

Кажется, ваша настройка php-fpm в порядке.

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

Добавляем к предложениям cyberx86:

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

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

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

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

Очень удобная команда для поиска памяти, занятой 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.