[文章作者:张宴 本文版本:v1.0 最后修改:2011.08.05 转载请注明原文链接:http://blog.zyan.cc/file_get_contents/]

  有时候,运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器,突然系统负载上升,使用 top 命令查看,很多 php-cgi 进程 CPU 使用率接近100%。后来,我通过跟踪发现,这类情况的出现,跟 PHP 的 file_get_contents() 函数有着密切的关系。

  大、中型网站中,基于 HTTP 协议的 API 接口调用,是家常便饭。PHP 程序员们喜欢使用简单便捷的 file_get_contents("http://example.com/") 函数,来获取一个 URL 的返回内容,但是,如果 http://example.com/ 这个网站响应缓慢,file_get_contents() 就会一直卡在那儿,不会超时。

  我们知道,在 php.ini 中,有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的以下参数:
  默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。修改该参数,设置一个 PHP 脚本最大执行时间是必要的,但是,治标不治本。例如改成 <value name="request_terminate_timeout">30s</value>,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免“502 Bad Gateway”。

  要做到彻底解决,只能让 PHP 程序员们改掉直接使用 file_get_contents("http://example.com/") 的习惯,而是稍微修改一下,加个超时时间,用以下方式来实现 HTTP GET 请求。要是觉得麻烦,可以自行将以下代码封装成一个函数。
  当然,导致 php-cgi 进程 CPU 100% 的原因不只有这一种,那么,怎么确定是 file_get_contents() 函数导致的呢?

  首先,使用 top 命令查看 CPU 使用率较高的 php-cgi 进程。

top - 10:34:18 up 724 days, 21:01,  3 users,  load average: 17.86, 11.16, 7.69
Tasks: 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:   8100996k total,  4320108k used,  3780888k free,   772572k buffers
Swap:  8193108k total,    50776k used,  8142332k free,   412088k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                              
10747 www       18   0  360m  22m  12m R 100.6 0.3    0:02.60 php-cgi                                                                                                              
10709 www       16   0  359m  28m  17m R 96.8  0.4    0:11.34 php-cgi                                                                                                              
10745 www       18   0  360m  24m  14m R 94.8  0.3    0:39.51 php-cgi                                                                                                              
10707 www       18   0  360m  25m  14m S 77.4  0.3    0:33.48 php-cgi                                                                                                              
10782 www       20   0  360m  26m  15m R 75.5  0.3    0:10.93 php-cgi                                                                                                              
10708 www       25   0  360m  22m  12m R 69.7  0.3    0:45.16 php-cgi                                                                                                              
10683 www       25   0  362m  28m  15m R 54.2  0.4    0:32.65 php-cgi                                                                                                              
10711 www       25   0  360m  25m  15m R 52.2  0.3    0:44.25 php-cgi                                                                                                              
10688 www       25   0  359m  25m  15m R 38.7  0.3    0:10.44 php-cgi                                                                                                              
10719 www       25   0  360m  26m  16m R  7.7  0.3    0:40.59 php-cgi

  找其中一个 CPU 100% 的 php-cgi 进程的 PID,用以下命令跟踪一下:
strace -p 10747

  如果屏幕显示:
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)

  那么,就可以确定是 file_get_contents() 导致的问题了。




技术大类 » Web服务器 | 评论(203) | 引用(0) | 阅读(194252)
智商测试 Homepage
2012-2-1 10:24
清洗剂 Homepage
2012-2-4 10:51
SK Email Homepage
2012-2-5 12:53
不错的文章哦
小叫花
2012-2-6 16:23
学习
游客 Email Homepage
2012-2-8 10:56
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)

这个说明了什么问题?是最后的timeout吗?
Tim Email Homepage
2012-2-9 11:16
都是技术控!
cold night Email Homepage
2012-2-20 09:59
不错,学习了
速度达 Email Homepage
2012-3-11 13:30
www.sududa888.com里面的后台表不对了。求您解决一下。
胖胖吉 Email Homepage
2012-4-12 17:52
受教了,以前网站挨过一次 一早上都是502 Bad Gateway 错误,后来经过排查是你说的这个原因。这篇文章真是相见恨晚啊。
kevin2 Email
2012-4-15 23:05
方法二int_set('default_socket_timeout', 30);file_get_contents("http://g.cn/");
dd
2012-4-23 12:48
你说的这个问题, 我也发现了, 有时候系统负载会突然增加, 然后处于一个相对稳定状态,如:40%多,那样,后来跟踪发现,有个别出fast-cgi线程运行时间很长,然后kill掉就没事了,我知道是网络相关函数问题,不过不能像你这样确定是具体哪一个函数,呵呵
Abercrombie Email Homepage
2012-5-9 10:34
Cependant, le plus rapidement, même en dépit Abercrombie du fait que vous vous rendez compte les avantages et comment relaxant c'est encore, malgré le fait que vous tend encore bien au sein de l'intérieur de la sauvegarde et de luxe dans votre maison à tout moment appartenant vers le soir ou le soir manquante de l'acquisition de crapahuter dans les un magasin à un autre essayer de localiser l'inconfort que vous essayez de trouver, vous allez vite être acheter pour le net seulement pour vos spécifications indépendamment de pas un problème c'est peut-être aAbercrombie de sortie que vous essayez de découvrir ou de tout autre type de Abercrombiesortie de vêtements d'achat en plus des vêtements finition unique spéciale robuste.
Hogan Email Homepage
2012-5-10 17:45
In che possono posso individuare un fabbro uno dei più affidabili Greater London? Nel caso in cui si vogliono ottenere le aziende particolari del vostro fabbro Grande Londra quindi si sta andando in vista di un individuo Hogan che è totalmente certificata che è successo con fiducia. Nel caso in cui si va a vedere Locallocksmith24hour. corp. britannico sarete in grado di ottenere probabilmente il più efficace fabbro Grande Londra sta offrendo.
hogan280 Email
2012-5-10 18:00
Nella segnalazione del Rochdale "processo grooming" molto è stato fatto del fatto che gli uomini erano in gran parte pakistani, mentre Hogan le 47 vittime, anche se solo sette hanno fornito prove - erano tutti bianchi e classe operaia. Le vittime avevano un'età compresa tra 13 e 15 anni al momento dell'abuso, e la polizia li ha descritti come da "caotica" e "Consiglio tenuta" sfondi.
小丁 Homepage
2012-5-16 16:20
学习了 。。一直关注楼主
cxf0401
2012-6-11 10:34
Michael Kors handbags outlet Bundled in the assortment are white mink Michael Kors handbags sporting chain handles in gleaming silver and the chocolate viscose tote with rabbit trim. Welcome to our online sales shop, where you can always buy the most affordable price to a your favorite Michael Kors outlet.
Vivienne Westwood Jewellery Email Homepage
2012-6-11 23:35
<p>yet you the united realm virtually you want to weren't you should with her yet yourselves styles, Vivienne Westwood written yourselves when shopping for you on your visitors anyhow. she took very leather, steel, darkish colors, way too short styles while your unrelenting rebellious you are not yet  <strong>vivienne westwood bags</strong>  you should then  <strong>vivienne westwood sale</strong>  supplemented your visitors together, pooling your respective personalities yet with its you the will last result. you the outcome, yes  <strong>Vivienne Westwood Jewellery</strong>  course, wound upward whilst jazz Rock. ,Look more related about <strong>Vivienne Westwood Jewellery</strong>:http://www.ukviviennewestwoodhandbags.com/ </br></p>
干货
2012-6-25 20:34
张兄的文章绝对干货
最好的家用洗车器
分页: 8/11 第一页 上页 3 4 5 6 7 8 9 10 11 下页 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]