Detailed explanation of php-fpm startup parameters and important configuration

Agree on several directories

  • /usr/local/php/sbin/php-fpm
  • /usr/local/php/etc/php-fpm.conf
  • /usr/local/php/etc/php.ini

First, the startup parameters of php-fpm

#test php-fpm configuration
/usr/local/php/sbin/php-fpm -t
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf -t
 
#start php-fpm
/usr/local/php/sbin/php-fpm
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf
 
#close php-fpm
kill -INT `cat /usr/local/php/var/run/php-fpm.pid`
 
#restart php-fpm
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

 

 

2. Detailed explanation of important parameters of php-fpm.conf

pid = run/php-fpm.pid
#pid setting, the default is var/run/php-fpm.pid in the installation directory, it is recommended to open
 
error_log = log/php-fpm.log
#Error log, var/log/php-fpm.log in the installation directory by default
 
log_level = notice
#Error level. Available levels are: alert (must be handled immediately), error (error condition), warning (warning condition), notice (generally important information), debug (debug information). Default: notice.
 
emergency_restart_threshold = 60
emergency_restart_interval = 60s
# Indicates that if the number of php-cgi processes with SIGSEGV or SIGBUS errors within the value set by emergency_restart_interval exceeds emergency_restart_threshold, php-fpm will restart gracefully. These two options are generally kept at their default values.
 
process_control_timeout = 0
#Set the timeout for the child process to accept the multiplexed signal of the main process. Available units: s (seconds), m (minutes), h (hours), or d (days) Default unit: s (seconds). Default value: 0.
 
daemonize = yes
#Execute fpm in the background, the default value is yes, if you can change it to no for debugging. In FPM, it is possible to run multiple process pools with different settings. These settings can be set individually for each process pool.
 
listen = 127.0.0.1:9000
#fpm listening port, that is, the address processed by php in nginx, generally the default value. Available formats are: 'ip:port', 'port', '/path/to/unix/socket'. It needs to be set for each process pool.
 
listen.backlog = -1
#backlog number, -1 means unlimited, determined by the operating system, just comment out this line. Backlog meaning reference: http://www.3gyou.cc/?p=41
 
listen.allowed_clients = 127.0.0.1
#Allow access to the IP of the FastCGI process, set any to unrestricted IP, if you want to set nginx of other hosts to access this FPM process, listen to a locally accessible IP. The default value is any. Each address is separated by commas. If not set or empty, any server requesting connection is allowed
 
listen.owner = www
listen.group = www
listen.mode = 0666
#unix socket setting options, if you use tcp access, you can comment here.
 
user = www
group = www
# account and group to start the process
 
pm = dynamic # For dedicated servers, pm can be set to static.
#How to control the child process, the options are static and dynamic. If static is selected, a fixed number of child processes is specified by pm.max_children. If dynamic is selected, it is determined by the down-opening parameter:
pm.max_children #, the maximum number of child processes
pm.start_servers #, the number of processes at startup
pm.min_spare_servers #, to ensure the minimum number of idle processes, if the idle process is less than this value, create a new child process
pm.max_spare_servers #, to ensure the maximum number of idle processes, if the idle process is greater than this value, this will be cleaned up
 
pm.max_requests = 1000
#Set the number of requests to serve before each child process respawns. Useful for third-party modules that may have memory leaks. If set to '0', requests are always accepted. Equivalent to the PHP_FCGI_MAX_REQUESTS environment variable. Default: 0.
 
pm.status_path = /status
#The URL of the FPM status page. If not set, the status page cannot be accessed. Default: none. munin monitoring will use
 
ping.path = /ping
# The ping URL of the FPM monitoring page. If not set, the ping page cannot be accessed. This page is used to externally detect whether the FPM is alive and can respond to requests. Please note that it must start with a slash (/).
 
ping.response = pong
#Used to define the return response of the ping request. The return is the text/plain format text of HTTP 200. Default value: pong.
 
request_terminate_timeout = 0
#Set the timeout abort time for a single request. This option may be useful for scripts whose 'max_execution_time' in php.ini settings does not abort for some special reasons. Set to '0' means 'Off'. When 502 errors occur frequently try changing this option.
 
request_slowlog_timeout = 10s
#When a request for the set timeout period, the corresponding PHP call stack information will be completely written to the slow log. Set to '0' means 'Off'
 
slowlog = log/$pool.log.slow
#Slow request record log, used with request_slowlog_timeout
 
rlimit_files = 1024
#Set the rlimit limit for file open descriptors. Default value: The system-defined value defaults to 1024 open handles, which can be viewed with ulimit -n and modified with ulimit -n 2048.
 
rlimit_core = 0
#Set the maximum limit value of the core rlimit. Available values: 'unlimited' , 0 or a positive integer. Default value: system defined value.
 
chroot =
#The Chroot directory at startup. The defined directory needs to be an absolute path. If not set, the chroot is not used.
 
chdir =
#Set the startup directory, which will be automatically Chdir to this directory at startup. The defined directory needs to be an absolute path. Default value: current directory, or / directory (when chrooted)
 
catch_workers_output = yes
#Redirect running stdout and stderr to the main error log file. If not set, stdout and stderr will be redirected to /dev/null according to FastCGI rules. Default: empty.

 

Three, common errors and solutions

1, resource problems caused by request_terminate_timeout

If the value of request_terminate_timeout is set to 0 or too long, it may cause resource problems in file_get_contents.

 

If the remote resource requested by file_get_contents responds too slowly, file_get_contents will stay stuck there and will not time out. We know that max_execution_time in php.ini can set the maximum execution time of PHP scripts, but in php-cgi(php-fpm), this parameter will not take effect. What really controls the maximum execution time of PHP scripts is the request_terminate_timeout parameter in the php-fpm.conf configuration file.

The default value of request_terminate_timeout is 0 seconds, that is, the PHP script will continue to execute. In this way, when all php-cgi processes are stuck in the file_get_contents() function, the Nginx+PHP WebServer can no longer process new PHP requests, and Nginx will return "502 Bad Gateway" to the user. It is necessary to modify this parameter and set the maximum execution time of a PHP script, but it is not a cure for the symptoms. For example, if it is changed to 30s, if file_get_contents() is slow to obtain web page content, it means that 150 php-cgi processes can only process 5 requests per second, and it is also difficult for WebServer to avoid "502 Bad Gateway". The solution is to set request_terminate_timeout to 10s or a reasonable value, or add a timeout parameter to file_get_contents.

$ctx = stream_context_create(array(
    'http' => array(
        'timeout' => 10 //Set a timeout in seconds
    )
));
 
file_get_contents($str, 0, $ctx);

 

2. Improper configuration of max_requests parameter may cause intermittent 502 errors:

pm.max_requests = 1000

 

设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 ’0′ 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.
这段配置的意思是,当一个 PHP-CGI 进程处理的请求数累积到 500 个后,自动重启该进程。

但是为什么要重启进程呢?

一般在项目中,我们多多少少都会用到一些 PHP 的第三方库,这些第三方库经常存在内存泄漏问题,如果不定期重启 PHP-CGI 进程,势必造成内存使用量不断增长。因此 PHP-FPM 作为 PHP-CGI 的管理器,提供了这么一项监控功能,对请求达到指定次数的 PHP-CGI 进程进行重启,保证内存使用量不增长。

正是因为这个机制,在高并发的站点中,经常导致 502 错误,我猜测原因是 PHP-FPM 对从 NGINX 过来的请求队列没处理好。不过我目前用的还是 PHP 5.3.2,不知道在 PHP 5.3.3 中是否还存在这个问题。

目前我们的解决方法是,把这个值尽量设置大些,尽可能减少 PHP-CGI 重新 SPAWN 的次数,同时也能提高总体性能。在我们自己实际的生产环境中发现,内存泄漏并不明显,因此我们将这个值设置得非常大(204800)。大家要根据自己的实际情况设置这个值,不能盲目地加大。

话说回来,这套机制目的只为保证 PHP-CGI 不过分地占用内存,为何不通过检测内存的方式来处理呢?我非常认同高春辉所说的,通过设置进程的峰值内在占用量来重启 PHP-CGI 进程,会是更好的一个解决方案。

3,php-fpm的慢日志,debug及异常排查神器:

request_slowlog_timeout设置一个超时的参数,slowlog设置慢日志的存放位置

tail -f /var/log/www.slow.log

 

上面的命令即可看到执行过慢的php过程。
大家可以看到经常出现的网络读取超过、Mysql查询过慢的问题,根据提示信息再排查问题就有很明确的方向了。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326524037&siteId=291194637