PHP's built-in function file_get_contents must have been designed to read hard disk files. Therefore, when reading file content, if the disk is busy or data preparation is slow, file_get_contents will wait, expect that the data will arrive quickly without waiting for even 1 ms. However, this stuff can also be used to read HTTP content, and the behavior of waiting for data is the same as reading files, while waiting for HTTP return and waiting for disk preparation data is not an order of magnitude in time, therefore, when file_get_contents is used to read HTTP content, it takes several seconds to wait, leading to soaring CPU usage. However, it seems that the new version of PHP fixes this issue or is related to some compilation items.
For more information, see:
Strace-RV-P <PHP process ID>-O strace. Log
Cat strace. Log
----------------------------------------------
0.000019 select (8, [7], [7], [], {15, 0}) = 1 (out [7], left {15, 0}) <0.000006>
0.000029 poll ([{FD = 7, events = Pollin | pollpri}], 1, 0) = 0 <0.000004>
0.000018 gettimeofday ({1340090123,417 745}, null) = 0 <0.000004>
0.000017 gettimeofday ({1340090123,417 763}, null) = 0 <0.000005>
0.000019 gettimeofday ({1340090123,417 781}, null) = 0 <0.000005>
0.000019 select (8, [7], [7], [], {15, 0}) = 1 (out [7], left {15, 0}) <0.000010>
0.000034 poll ([{FD = 7, events = Pollin | pollpri}], 1, 0) = 0 <0.000005>
0.000018 gettimeofday ({1340090123,417 853}, null) = 0 <0.000005>
0.000018 gettimeofday ({1340090123,417 871}, null) = 0 <0.000005>
0.000019 gettimeofday ({1340090123,417 889}, null) = 0 <0.000005>
0.000019 select (8, [7], [7], [], {15, 0}) = 1 (out [7], left {15, 0}) <0.000006>
0.000028 poll ([{FD = 7, events = Pollin | pollpri}], 1, 0) = 0 <0.000005>
0.000018 gettimeofday ({1340090123,417 956}, null) = 0 <0.000007>
0.000020 gettimeofday ({1340090123,417 974}, null) = 0 <0.000005>
0.000018 gettimeofday ({1340090123,417 993}, null) = 0 <0.000004>
0.000032 select (8, [7], [7], [], {15, 0}) = 1 (out [7], left {15, 0}) <0.000006>
0.000036 poll ([{FD = 7, events = Pollin | pollpri}], 1, 0) = 0 <0.000005>
0.000019 gettimeofday ({1340090123,418 080}, null) = 0 <0.000005>
0.000018 gettimeofday ({1340090123,418 097}, null) = 0 <0.000005>
0.000020 gettimeofday ({1340090123,418 117}, null) = 0 <0.000005>
......
----------------------------------------------
PHP enters a non-blocking poll loop for several seconds until data is returned, and CPU usage will soar during this period.
To read HTTP content, it is best to avoid using file_get_contents. you can replace it with the following custom function:
function url_get_contents($strUrl, $boolUseCookie=false){$ch = curl_init($strUrl);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_TIMEOUT, 5);curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_HTTPGET, true); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);curl_setopt($ch, CURLOPT_MAXREDIRS, 3);if ($boolUseCookie && is_array($_COOKIE) && count($_COOKIE) > 0) {$cookie_str = '';foreach($_COOKIE as $key => $value) {$cookie_str .= "$key=$value; "; }curl_setopt($ch, CURLOPT_COOKIE, $cookie_str);}$response = curl_exec($ch);if (curl_errno($ch) != 0) {return false;}curl_close($ch);return $response;}