Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1208821
  • 博文数量: 252
  • 博客积分: 5421
  • 博客等级: 大校
  • 技术积分: 2418
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-17 12:59
文章分类

全部博文(252)

文章存档

2017年(3)

2016年(18)

2015年(31)

2014年(18)

2013年(7)

2012年(8)

2011年(12)

2010年(30)

2009年(32)

2008年(57)

2007年(36)

分类: 系统运维

2012-06-20 01:42:01

php的内置函数file_get_contents想必当初是为读取硬盘文件设计的,所以在读取文件内容时如果磁盘繁忙或准备数据慢,file_get_contents会进入忙等待,期许数据会飞快的到来,而不会等哪怕1ms。但是这个东东也允许用来读取http内容,而且等待数据的行为和读取文件一样,而等待http返回和等待磁盘准备数据在时间上可不是一个量级的,所以当file_get_contents用来读取http内容时就进入了秒级的忙等待,从而导致cpu飙升。不过貌似新版本的php修复了该问题,或者和某些编译项有关。

情景见下:
strace -rv -p -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, 417745}, NULL) = 0 <0.000004>
0.000017 gettimeofday({1340090123, 417763}, NULL) = 0 <0.000005>
0.000019 gettimeofday({1340090123, 417781}, 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, 417853}, NULL) = 0 <0.000005>
0.000018 gettimeofday({1340090123, 417871}, NULL) = 0 <0.000005>
0.000019 gettimeofday({1340090123, 417889}, 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, 417956}, NULL) = 0 <0.000007>
0.000020 gettimeofday({1340090123, 417974}, NULL) = 0 <0.000005>
0.000018 gettimeofday({1340090123, 417993}, 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, 418080}, NULL) = 0 <0.000005>
0.000018 gettimeofday({1340090123, 418097}, NULL) = 0 <0.000005>
0.000020 gettimeofday({1340090123, 418117}, NULL) = 0 <0.000005>
... ...
----------------------------------------------
php进入了持续数秒的非阻塞poll循环,直到数据返回,cpu使用率在此期间会飙升。

对于读取http内容,最好避免用file_get_contents,可以改用下面的自定义函数取代:

点击(此处)折叠或打开

  1. function url_get_contents($strUrl, $boolUseCookie=false)
  2. {
  3.     $ch = curl_init($strUrl);
  4.     curl_setopt($ch, CURLOPT_HEADER, 0);
  5.     curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  6.     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
  7.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  8.     curl_setopt($ch, CURLOPT_HTTPGET, true);
  9.     curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  10.     curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
  11.     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  12.     curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
  13.     if ($boolUseCookie && is_array($_COOKIE) && count($_COOKIE) > 0) {
  14.         $cookie_str = '';
  15.         foreach($_COOKIE as $key => $value) {
  16.             $cookie_str .= "$key=$value; ";
  17.         }
  18.         curl_setopt($ch, CURLOPT_COOKIE, $cookie_str);
  19.     }
  20.     $response = curl_exec($ch);
  21.     if (curl_errno($ch) != 0) {
  22.         return false;
  23.     }
  24.     curl_close($ch);
  25.     return $response;    
  26. }


阅读(1655) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~