有时候,运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器,突然系统负载上升,使用 top 命令查看,很多 php-cgi 进程 CPU 使用率接近100%.后来,我通过跟踪发现,这类情况的出现,跟 PHP 的 file_get_contents() 函数有着密切的关系.一般网站中,基于命令行的php脚本来做采集任务是家常便饭,PHP程序员们喜欢使用简单便捷的 file_get_contents(“http://www.xxx.com/”)函数,来获取一个URL 的返回内容,但是,如果 http://example.com/ 这个网站响应缓慢,file_get_contents() 就会一直卡在那儿,不会超时.
要做到彻底解决,只能让 PHP 程序员们改掉直接使用 file_get_contents(“http://example.com/”) 的习惯,而是稍微修改一下,加个超时时间,用以下方式来实现 HTTP GET 请求。要是觉得麻烦,可以自行将以下代码封装成一个函数
<?php $ctx = stream_context_create(array( 'http' => array( 'timeout' => 2 //设置一个超时时间,单位为秒 ) ) ); file_get_contents("http://example.com/", 0, $ctx);
也可以这样做:
直接在php.ini中修改 default_socket_timeout =2
或ini_set(‘default_socket_timeout’,2);
或者用curl代替:
function new_file_get_contents($url){ $result = ''; $ch = curl_init(); $options = array( CURLOPT_URL => $url, CURLOPT_CONNECTTIMEOUT => 10, //连接超时 CURLOPT_TIMEOUT => 10, //接收数据时超时设置 CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => $method == 'post' ? 1 : 0, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0' ); curl_setopt_array($ch, $options); $result = curl_exec($ch); curl_close($ch); return $result; }
当然,导致php进程CPU100%的原因不只有这一种,那么,怎么确定是file_get_contents()函数导致的呢?首先,使用top命令查看CPU使用率较高的php进程.
找其中一个CPU100%的php进程的 PID,用以下命令跟踪一下:
strace -p xxxxx
如果屏幕显示:
select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0}) poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout) select(6, [5], [5], [], {15, 0}) = 1 (out [5], left {15, 0})
那么,就可以确定是file_get_contents()导致的问题了
whose brand new fiance Matthew Bellamy skipped the fashion festivities
gay porn The adventure of a swimwear designer at MBIFW 2011
gay pornOld Fashioned German Potato Soup Recipe