Sometimes, running nginx, PHP-CGI (PHP-FPM) web service Linux server, suddenly the system load increases, use the top command to view, many PHP-CGI process CPU usage is close to 100%. Later, I found through tracking that the appearance of such cases is closely related to the file_get_contents () function of PHP.
HTTP-based API calls are common for large and medium-sized websites. PHP programmers like to use the simple and convenient file_get_contents ("http://example.com/") function to get the returned content of a URL, but if the http://example.com/This site responds slowly, file_get_contents () it will remain there and will not time out.
We know that in PHP. in INI, max_execution_time can be used to set the maximum execution time of PHP scripts. However, this parameter does not take effect in PHP-CGI (PHP-FPM. Which of the following parameters in the php-fpm.conf configuration file can really control the maximum execution time of PHP scripts:
View plainprint?
- The timeout (in seconds) for serving a single request after which the worker process will be terminated
- Shocould be used when 'max _ execution_time 'ini option does not stop script execution for some reason
- '0s' means 'off'
- <Value name = "request_terminate_timeout"> 0 S </value>
The default value is 0 seconds. That is to say, the PHP script will be executed continuously. 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, nginx returns "502 Bad Gateway" to the user ". Modify this parameter to set the maximum execution time of a PHP script. For example, if you change it to <value name = "request_terminate_timeout"> 30 S </value>, if file_get_contents () is slow to obtain webpage content, it means 150 PHP-CGI processes, only five requests can be processed per second. It is also difficult for webserver to avoid "502 Bad Gateway ".
To achieve a thorough solution, can only let PHP programmers get rid of the habit of using file_get_contents ("http://example.com/"), but slightly modify, add a timeout time, use the following methods to implement http get requests. If you are in trouble, you can encapsulate the following code into a function.
View plainprint?
- <? PHP
- $ CTX = stream_context_create (Array (
- 'Http' => array (
- 'Timeout' => 1 // set a timeout time, in seconds
- )
- )
- );
- File_get_contents ("http://example.com/", 0, $ CTX );
- ?>
Of course, this is not the only reason for the CPU 100% of the PHP-CGI process. So, how can we determine it is caused by the file_get_contents () function?
First, run the TOP command to view the PHP-CGI process with high CPU usage.
Top-10:34:18 up 724 days, 3 users, load average: 17.86, 11.16, 7.69
Task: 561 total, 15 running, 546 sleeping, 0 stopped, 0 zombie
CPU (s): 5.9% us, 4.2% Sy, 0.0% Ni, 89.4% ID, 0.2% wa, 0.0% hi, 0.2% Si, 0.0% St
Mem: 8100996 k total, 4320108 K used, 3780888 K free, 772572 K Buffers
Swap: 8193108 k total, 50776 K used, 8142332 K free, 412088 K cached
PID user PR Ni virt res shr s % CPU % mem time + command
10747 WWW 18 0 360 m 22 m 12 M r 100.6 0: 02. 60 PHP-CGI
10709 WWW 16 0 359 M 28 m 17 M r 96.8 0.4. 34 PHP-CGI
10745 WWW 18 0 360 m 24 m 14 M r 94.8 0.3. 51 PHP-CGI
10707 WWW 18 0 360 m 25 m 14 m s 77.4 0: 33. 48 PHP-CGI
10782 WWW 20 0 360 m 26 m 15 M r 75.5 0.3. 93 PHP-CGI
10708 WWW 25 0 360 m 22 m 12 M r 69.7 0.3. 16 PHP-CGI
10683 WWW 25 0 362 m 28 m 15 M r 54.2 0.4. 65 PHP-CGI
10711 WWW 25 0 360 m 25 m 15 M r 52.2 0.3. 25 PHP-CGI
10688 WWW 25 0 359 m 25 m 15 M r 38.7 0.3. 44 PHP-CGI
10719 WWW 25 0 360 m 26 M 16 M r 7.7 0.3. 59 PHP-CGI
Find the PID of one of the PHP-CGI processes with CPU 100% and run the following command to trace the PID:
Strace-P 10747
If the screen displays:
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
Select (7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0 })
Poll ([{FD = 6, events = Pollin}], 1, 0) = 0 (timeout)
The problem is caused by file_get_contents.
Source: http://blog.s135.com/file_get_contents/2/1/