PHP编程:PHP-CGI 历程 CPU 100% 与 file_get_co...
左手拿着MOTOLOLA右手拿着NOKIA,要多潇洒,有多潇洒,哈哈,终于学会了,但是可能这个时候,又会有人不经意的拍拍肩膀对你说:哥们,别高兴的太早,你还是菜鸟,离学会还差着一大截呢! 有时分,运转 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 设置装备摆设文件中的以下参数: The timeout (in seconds) for serving a single request after which the worker process will be terminated
Should be used when 'max_execution_time' ini option does not stop script execution for some reason
'0s' means 'off'
<value name="request_terminate_timeout">0s</value>
默许值为 0 秒,也就是说,PHP 剧本会一向履行下去。如许,当一切的 php-cgi 历程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已没法再处置新的 PHP 恳求了,Nginx 将给用户前往“502 Bad Gateway”。修正该参数,设置一个 PHP 剧本最大履行工夫是需要的,然而,治本不治标。例如改成 30s,假如产生 file_get_contents() 获得网页内容较慢的情形,这就意味着 150 个 php-cgi 历程,每秒钟只能处置 5 个恳求,WebServer 一样很难防止“502 Bad Gateway”。
要做到完全处理,只能让 PHP 法式员们改失落直接利用 file_get_contents("http://example.com/") 的习气,而是略微修正一下,加个超不时间,用以下体例来完成 HTTP GET 恳求。如果感觉费事,可以自即将以下代码封装成一个函数。 <?php
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1 //设置一个超不时间,单元为秒
)
)
);
file_get_contents("http://example.com/", 0, $ctx);
?>
固然,招致 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 PRNIVIRTRESSHR S %CPU %MEM TIME+COMMAND
10747 www 18 0360m22m12m R 100.6 0.3 0:02.60 php-cgi
10709 www 16 0359m28m17m R 96.80.4 0:11.34 php-cgi
10745 www 18 0360m24m14m R 94.80.3 0:39.51 php-cgi
10707 www 18 0360m25m14m S 77.40.3 0:33.48 php-cgi
10782 www 20 0360m26m15m R 75.50.3 0:10.93 php-cgi
10708 www 25 0360m22m12m R 69.70.3 0:45.16 php-cgi
10683 www 25 0362m28m15m R 54.20.4 0:32.65 php-cgi
10711 www 25 0360m25m15m R 52.20.3 0:44.25 php-cgi
10688 www 25 0359m25m15m R 38.70.3 0:10.44 php-cgi
10719 www 25 0360m26m16m R7.70.3 0:40.59 php-cgi
找个中一个 CPU 100% 的 php-cgi 历程的 PID,用以下号令跟踪一下: strace -p 10747 select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, , , [], {15, 0}) = 1 (out , left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
那末,就能够肯定是 file_get_contents() 招致的成绩了。
<P style="TEXT-INDENT: 2em">
对于PHP的语法结构,刚开始真的很不习惯,真搞不懂为什么每个变量之前都要加个“$”符号,每个语句写完之后都必须加上“分号”来表示此句已经结束,还有,PHP对字母的大小写是敏感的,写的时候一定要注意大小写的区别。 Ps:以上纯属原创,如有雷同,纯属巧合 我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能: 建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。 建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。 当留言板完成的时候,下步可以把做1个单人的blog程序,做为目标, 首先声明:我是一个菜鸟,是一个初学者。学习了一段php后总是感觉自己没有提高,无奈。经过反思我认为我学习过程中存在很多问题,我改变了学习方法后自我感觉有了明显的进步。 写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。 php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会) 再就是混迹于论坛啦,咱们的phpchina的论坛就很强大,提出的问题一般都是有达人去解答的,以前的帖子也要多看看也能学到不少前辈们的经验。别的不错的论坛例如php100,javaeye也是很不错的。 写的比较杂,因为我也是个新手,不当至于大家多多指正。 有时候汉字的空格也能导致页面出错,所以在写代码的时候,要输入空格最好用引文模式。 写的比较杂,因为我也是个新手,不当至于大家多多指正。 本文当是我的笔记啦,遇到的问题随时填充 曾经犯过一个很低级的错误,我在文件命名的时候用了一个横线\\\\\\\'-\\\\\\\' 号,结果找了好几个小时的错误,事实是命名的时候 是不能用横线 \\\\\\\'-\\\\\\\' 的,应该用的是下划线\\\\\\\'_\\\\\\\' ; ,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。 实践是检验自己会不会的真理。 有时候汉字的空格也能导致页面出错,所以在写代码的时候,要输入空格最好用引文模式。 当留言板完成的时候,下步可以把做1个单人的blog程序,做为目标,
页:
[1]