Optimization and analysis of PHP-FPM process in Linux

Source: Internet
Author: User
Tags fpm http 200 memory usage mysql query php script vps

On several offline servers that are not very busy, the number of PHP-FPM processes is found to be more than 500, and some processes run for several months.

The following troubleshooting was performed to determine if there is a problem with the PHPFPM operation and whether a reboot is required.

To see if these processes are started properly

Because the start and recycle times of the worker process are printed at the notice level in Php-fpm.log, you can check which PHP is not logged to (PS Axuf can view the parent-child relationship to the process) by using the following statement:

The code is as follows Copy Code

$CD/path/to/php-fpm.log

$for word in ' PS Axu | grep php | Perl-ne ' Chomp; @tmp =split "+", $_; Print $tmp [1]. " n "; ' ` ; Do if grep $word php-fpm.log >/dev/null; Then Echo-n ';  else echo $word; fi; Done

The execution result found that 173 processes were not logged and that some of them could have been php-fpm when the parent process was started, so they were not logged. Fork But there are dozens of left, and I don't know why.

Confirm that the process is alive

Login through root account, Strace-p <pid>, where PID is one of the top 173 processes. Discovering normal scrolling and seeing calls to the PHP method, it is determined that the process survives and can provide services.

Why are there so many processes in existence?

Although there is no impact on the service, but so many processes exist, is it normal?

The first thing to look at is php-fpm.conf:

The code is as follows Copy Code
PM = dynamic
Pm.max_children = 8192
Pm.start_servers = 128
Pm.min_spare_servers = 128
Pm.max_spare_servers = 1024
Pm.max_requests = 500000

Because our idle process is configured to 128 ~ 1024, and the Max_request is configured to 50w, and before the machine traffic is small, it may take a long time, the process will not because of processing max_request a request, or more than the number of spare_servers and be recycled.

While a php-fpm process consumes around 12m of unshared memory, it is sufficient to support 1k PHP-FPM processes according to machine configuration, CPU, and memory configuration.

To agree on several directories

The code is as follows Copy Code
/usr/local/php/sbin/php-fpm
/usr/local/php/etc/php-fpm.conf
/usr/local/php/etc/php.ini

First, the PHP-FPM start parameter

The code is as follows Copy Code
#测试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

#启动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

#关闭php-FPM
Kill-int ' Cat/usr/local/php/var/run/php-fpm.pid '

#重启php-FPM
KILL-USR2 ' Cat/usr/local/php/var/run/php-fpm.pid '

Two, php-fpm.conf important parameter detailed explanation

The code is as follows Copy Code
PID = Run/php-fpm.pid
#pid设置, the default var/run/php-fpm.pid in the installation directory, recommended to open

Error_log = Log/php-fpm.log
#错误日志, default Var/log/php-fpm.log in the installation directory

Log_level = Notice
#错误级别. Available levels are: alert (must be processed immediately), error (Errors), warning (warning condition), notice (general important information), debug (debug information). Default: Notice.

Emergency_restart_threshold = 60
Emergency_restart_interval = 60s
#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi Number of processes if more than Emergency_restart_threshold, PHP-FPM will gracefully restart. These two options generally keep the default values.

Process_control_timeout = 0
#设置子进程接受主进程复用信号的超时时间. Available units: s (seconds), M (minutes), H (Hours), or D (day) default units: S (sec). Default value: 0.

Daemonize = yes
#后台执行fpm, the default value is yes, if you want to change to no for debugging. In FPM, you can use different settings to run multiple process pools. These settings can be set individually for each process pool.

Listen = 127.0.0.1:9000
#fpm监听端口, that is, the address of PHP processing in Nginx, the general default value can be. Available formats are: ' Ip:port ', ' Port ', '/path/to/unix/socket '. Each process pool needs to be set.

Listen.backlog =-1
#backlog数, 1 means no limit, and the operating system decides that this row is commented out. Backlog meaning reference: http://www.3gyou.cc/?p=41

Listen.allowed_clients = 127.0.0.1
#允许访问FastCGI进程的IP, set any to not restrict IP, if you want to set other host Nginx also can access this FPM process, listen to set the cost of access to IP. The default value is any. Each address is separated by commas. Allow any server to request a connection if it is not set or is empty

Listen.owner = www
Listen.group = www
Listen.mode = 0666
#unix socket setting option, if you are using TCP access, Comment here.

user = www
Group = www
#启动进程的帐户和组

PM = Dynamic #对于专用服务器, PM can be set to static.
#如何控制子进程, the options are static and dynamic. If you select static, Pm.max_children specifies the number of fixed child processes. If dynamic is selected, it is determined by the next open parameter:
Pm.max_children #, maximum number of child processes
Pm.start_servers #, number of processes at startup
Pm.min_spare_servers #, guarantees the minimum number of idle processes, and creates a new child process if the idle process is less than this value
Pm.max_spare_servers #, guarantees the maximum number of idle processes, and cleans if the idle process is greater than this value

pm.max_requests = 1000
#设置每个子进程重生之前服务的请求数. is useful for Third-party modules that may have memory leaks. If set to ' 0 ', the request is always accepted. Equivalent to php_fcgi_max_requests environment variables. Default value: 0.

Pm.status_path =/status
#FPM状态页面的网址. If it is not set, the status page cannot be accessed. Default value: None. Munin monitoring will use the

Ping.path =/ping
#FPM监控页面的ping网址. If it is not set, the ping page cannot be accessed. This page is used to externally detect if FPM is alive and can respond to requests. Please note that you must start with a slash (/).

Ping.response = Pong
#用于定义ping请求的返回相应. Returns the Text/plain-formatted text for HTTP 200. Default value: Pong.

Request_terminate_timeout = 0
#设置单个请求的超时中止时间. This option may be useful for the ' max_execution_time ' in the php.ini setting that does not abort the script for some special reason. Set to ' 0 ' means ' off '. You can try to change this option when a 502 error occurs frequently.

Request_slowlog_timeout = 10s
#当一个请求该设置的超时时间后, the corresponding PHP call stack information is fully written to the slow log. Set to ' 0 ' means ' off '

Slowlog = log/$pool. Log.slow
#慢请求的记录日志, use with Request_slowlog_timeout

Rlimit_files = 1024
#设置文件打开描述符的rlimit限制. Default value: The system-defined value default open handle is 1024, you can use Ulimit-n view, ulimit-n 2048 modify.

Rlimit_core = 0
#设置核心rlimit最大限制值. Available values: ' Unlimited ', 0, or positive integer. Default value: System-defined value.

Chroot =
#启动时的Chroot目录. The defined directory needs to be an absolute path. If it is not set, then chroot is not used.

ChDir =
#设置启动目录, it is automatically chdir to the directory when it is started. The defined directory needs to be an absolute path. Default value: Current directory, or/directory (chroot)

Catch_workers_output = yes
#重定向运行过程中的stdout和stderr到主要的错误日志文件中. If there are no settings, stdout and stderr will be redirected to/dev/null according to the FASTCGI rules. Default value: null.

Third, common mistakes and solution arrangement

Resource problems caused by 1,request_terminate_timeout

A request_terminate_timeout value that is set to 0 or too long may cause a file_get_contents resource problem.

If the remote resource requested by file_get_contents is slow, file_get_contents will be stuck there without timing out. We know php.ini inside Max_execution_time can set the maximum execution time for a PHP script, but in php-cgi (PHP-FPM), the parameter does not work. The real ability to control the maximum execution time of a PHP script is the request_terminate_timeout parameter in the php-fpm.conf configuration file.

The

request_terminate_timeout default value is 0 seconds, which means that the PHP script will continue to execute. In this way, when all the php-cgi processes are stuck in the file_get_contents () function, the WebServer of this nginx+php is no longer able to process the new PHP request, and Nginx will return "502 bad Gateway" to the user. Modify this parameter to set a PHP script maximum execution time is necessary, but the symptom does not cure the root causes. For example, to 30s, if file_get_contents () to get the content of the Web page is slow, which means that 150 php-cgi process, only 5 requests per second, WebServer also difficult to avoid "502 bad Gateway." The solution is to set the request_terminate_timeout to 10s or a reasonable value, or to add a timeout parameter to the file_get_contents.

The code is as follows Copy Code

$ctx = stream_context_create (Array (
' http ' => array (
' Timeout ' => 10//Set a timeout in seconds
)
));

file_get_contents ($str, 0, $ctx);

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

The code is as follows Copy Code

pm.max_requests = 1000

Sets the number of requests for services before each subprocess is reborn. is useful for Third-party modules that may have memory leaks. If set to ' 0′, the request is always accepted. Equivalent to php_fcgi_max_requests environment variables. Default value: 0.
This configuration means that the process is automatically restarted when the number of requests processed by a php-cgi process accumulates to 500.

But why restart the process?

Generally in the project, we will use more or less the Third-party library of PHP, these third-party libraries often have memory leaks, if not periodically restart the php-cgi process, it is bound to cause memory usage continues to grow. Therefore, as a php-cgi manager, PHP-FPM provides such a monitoring function to restart the php-cgi process with a specified number of requests to ensure that the amount of memory is not increased.

Precisely because of this mechanism, in the high concurrency of the site, often led to 502 errors, I guess the reason is php-fpm to the request from the NGINX queue did not deal well. However, I am currently using PHP 5.3.2, do not know if there is still this problem in the PHP 5.3.3.

Our solution now is to set this value as large as possible, to minimize the number of php-cgi SPAWN and to improve overall performance. In our own actual production environment, we found that the memory leak is not obvious, so we set this value very large (204800). We should set this value according to their actual situation, not blindly increase.

In other words, the purpose of this mechanism is only to ensure that the php-cgi not excessive memory, why not through the detection of memory methods to deal with it? I very much agree with Gao Chunhui that it is a better solution to restart the php-cgi process by setting the peak intrinsic footprint of the process.

3,PHP-FPM slow log, debug and abnormal troubleshooting artifacts:

The code is as follows Copy Code

Request_slowlog_timeout sets a timeout parameter, Slowlog sets the location where the slow log is stored

1
Tail-f/var/log/www.slow.log

The above command to see the slow-performing PHP process.
You can see that often appear in the network read more than, the MySQL query too slow problem, according to the information and then troubleshoot the problem has a very clear direction.
Startup parameters and important configuration


PHP-FPM Optimization

1, php-fpm optimization parameter introduction

They were: PM, Pm.max_children, Pm.start_servers, Pm.min_spare_servers, Pm.max_spare_servers.

PM: In that way, there are two values that can be selected, either static (static) or dynamic.
In older versions, dynamic is called Apache-like. This should be noted in the description of the configuration file.

The following 4 parameters mean:

Pm.max_children: Number of PHP-FPM processes opened in static mode
Pm.start_servers: Number of starting PHP-FPM processes in dynamic mode
Pm.min_spare_servers: Minimum number of PHP-FPM processes in dynamic mode
Pm.max_spare_servers: Maximum number of PHP-FPM processes in dynamic mode
Difference:

If the DM is set to static, then only pm.max_children this parameter is in effect. The system will turn on the set number of PHP-FPM processes.
If the DM is set to dynamic, then the Pm.max_children parameter fails and the following 3 parameters take effect.
The system starts the Pm.start_servers PHP-FPM process at the start of the PHP-FPM run.
Then the number of php-fpm processes between Pm.min_spare_servers and Pm.max_spare_servers is dynamically adjusted according to the requirements of the system

2, the server specific configuration

For our server, which implementation is better to choose? In fact, as with Apache, the running PHP program is more or less a problem with memory leaks after the execution is complete.
This is why the beginning of a PHP-FPM process consumes only about 3M of memory, running for a period of time will rise to 20-30m reasons.

For servers with large memory (such as 8G or more), it is actually more appropriate to specify a static Max_children, since it does not require additional process-number control to improve efficiency.
Because the frequent switch php-fpm process will sometimes lag, so the memory is large enough to open the static effect will be better. The number can also be obtained according to the memory/30m, such as 8GB memory can be set to 100,
Then the memory that PHP-FPM consumes can control the appearance of 2g-3g. If the memory is slightly smaller, such as 1G, then specifying a static number of processes is more conducive to server stability.
This can ensure that php-fpm only get enough memory, will not allocate a lot of memory to other applications to use, will make the system more smooth operation.

For small memory servers, such as 256M memory VPS, even according to a 20M of memory to calculate, 10 php-cgi process will consume 200M memory, the system crash should be very normal.
Therefore, you should try to control the number of PHP-FPM processes, the general clarity of other applications occupied by the memory, give it a static small number, will make the system more stable. or using dynamic methods,
Because the dynamic way will end the redundant process, can reclaim some memory, so it is recommended to use less memory servers or VPS. The specific maximum quantity is obtained according to the memory/20m.
For example, 512M VPS, recommended pm.max_spare_servers set to 20. As for Pm.min_spare_servers, it is recommended that the server's load situation to set, such as the server is just the deployment of PHP environment, the more appropriate value between 5~10.

This server configuration

1, server basic information:

Hard disk: Data disk 30G, system disk 20G
Memory: 1.5G
CPU: Dual-core
System: CentOS 6.3 64-bit
Bandwidth: Exclusive 2M

2, deployment of the application

Git, SVN, Apache, Tomcat, PHP, Nginx, Mysql, JDK

3, after the optimization of the parameters

The code is as follows Copy Code


PM = dynamic
Pm.start_servers = 5
Pm.min_spare_servers = 2
Pm.max_spare_servers = 8


php5.3.3 after PHP-FPM process management mode

PHP-FPM provides a better way to manage PHP processes, can effectively control memory and process, can smooth overload PHP configuration, than spawn-fcgi has more advantages, so by the official PHP included. After php5.3.3./configure with –enable-fpm parameters to open php-fpm.

Using PHP-FPM to control the fastcgi process of php-cgi

The code is as follows Copy Code

/usr/local/php/sbin/php-fpm{start|stop|quit|restart|reload|logrotate}

--start start the fastcgi process of PHP

--stop forced to terminate PHP fastcgi process

--quit smooth termination of PHP fastcgi process

--restart Restart PHP's fastcgi process

--reload to reload PHP php.ini

--logrotate log file back on

PHP-FPM currently has two main branches, corresponding to the previous version of php-5.3.3 and php-5.3.3 later versions. In the 5.2.x version, php-fpm.conf uses the XML format, and in the new 5.3.3 version, the php.ini is the same configuration style. There are two ways to manage PHP-FPM processes--static and dynamic in later versions of 5.5.3. The configuration in the specific/usr/local/php/conf/php-fpm.conf.default is as follows:


; Choose How the Process manager would control the number of child processes.
; Possible Values:
; Static-a fixed number (pm.max_children) of child processes;
; Dynamic-the number of child processes are set dynamically based on the
; Following directives. With this process management, there would be
; Always at least 1 children.
; Pm.max_children-the Maximum number of children that can
; Be alive in the same time.
; Pm.start_servers-the number of children created on startup.
; Pm.min_spare_servers-the minimum number of children in ' idle '
; State (waiting to process). If the number
; of ' idle ' processes is less than this
; Number then some children would be created.
; Pm.max_spare_servers-the Maximum number of children in ' idle '
; State (waiting to process). If the number
; of ' idle ' processes is greater than this
; Number then some children would be killed.
; Ondemand-no children are created at startup. Children'll be forked when
; New requests'll connect. The following parameter are used:
; Pm.max_children-the Maximum number of children that
; can be alive in the same time.
; Pm.process_idle_timeout-the number of seconds after which
; An idle process would be killed.
; Note:this value is mandatory.
PM = dynamic


From the above you can see that the default is enabled dynamic management. And the number of PHP-FPM process is dynamic, the first is the number of pm.start_servers specified, if more requests, it will automatically increase, to ensure that the number of idle processes is not less than pm.min_spare_servers, if the number of processes are more, will be the corresponding clean-up, Ensure that the number of unnecessary processes is not more than pm.max_spare_servers. You can also see the settings in the above configuration file that involve four parameters, which are as follows:
Pm.max_children: The number of PHP-FPM processes that are open in static mode.
Pm.start_servers: The number of starting PHP-FPM processes in dynamic mode.
Pm.min_spare_servers: The minimum number of PHP-FPM processes under dynamic mode.
Pm.max_spare_servers: The maximum number of PHP-FPM processes under dynamic mode.

If the DM is set to static, then only pm.max_children this parameter is in effect. The system will turn on the set number of PHP-FPM processes.
If the DM is set to dynamic, then the Pm.max_children parameter fails and the following 3 parameters take effect. The system starts the Pm.start_servers PHP-FPM process at the start of the PHP-FPM operation, and then dynamically pm.min_spare_servers and pm.max_spare_ according to the requirements of the system Adjusts the number of PHP-FPM processes between servers.

So, what's the best way to do this for our servers? In fact, as with Apache, the running PHP program is more or less a problem with memory leaks after the execution is complete. This is why the beginning of a PHP-FPM process consumes only about 3M of memory, running for a period of time will rise to 20-30m reasons.

For servers with large memory (such as 8G or more), it is actually more appropriate to specify a static Max_children, since it does not require additional process-number control to improve efficiency. Because the frequent switch php-fpm process will sometimes lag, so the memory is large enough to open the static effect will be better. For example, 8GB memory can be set to 100, then PHP-FPM memory can control the appearance of 2g-3g. , if the database and Web applications are on different servers, the machine will only run on Web applications and can be driven to around 300. If the memory is slightly smaller, such as 1G, then specifying a static number of processes is more conducive to server stability. This can ensure that php-fpm only get enough memory, will not allocate a lot of memory to other applications to use, will make the system more smooth operation.

For small memory servers, such as 256M memory VPS, even according to a 20M of memory to calculate, 10 php-cgi process will consume 200M memory, the system crash should be very normal. Therefore, you should try to control the number of PHP-FPM processes, the general clarity of other applications occupied by the memory, give it a static small number, will make the system more stable. Or use dynamic mode, because the dynamic way will end off redundant processes, you can reclaim some memory, so the recommended in less memory servers or VPS. For example, 512M VPS, recommended pm.max_spare_servers set to 20. As for Pm.min_spare_servers, it is recommended to set the server's load, the appropriate value between 5~10.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.