PHP-CGI 进程 CPU 100% 与 file

  有时候,运行 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      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() 导致的问题了。

时间: 2024-09-17 01:21:52

PHP-CGI 进程 CPU 100% 与 file的相关文章

PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析_php技巧

后来,我通过跟踪发现,这类情况的出现,跟 PHP 的 file_get_contents() 函数有着密切的关系. 大.中型网站中,基于 HTTP 协议的 API 接口调用,是家常便饭.PHP 程序员们喜欢使用简单便捷的 file_get_contents("http://example.com/") 函数,来获取一个 URL 的返回内容,但是,如果 http://example.com/ 这个网站响应缓慢,file_get_contents() 就会一直卡在那儿,不会超时. 我们知道

PHP-FPM进程CPU 100% 问题解决办法

一.进程跟踪  代码如下 复制代码 # top //找出CPU使用率高的进程PID # strace -p PID //跟踪进程 # ll /proc/PID/fd //查看该进程在处理哪些文件 将有可疑的PHP代码修改之,如:file_get_contents没有设置超时时间. 二.内存分配 如果进程跟踪无法找到问题所在,再从系统方面找原因,会不会有可能内存不够用?据说一个较为干净的PHP-CGI打开大概20M-30M左右的内存,决定于PHP模块开启多少. 通过pmap指令查看PHP-CGI进

file_get_contents 导入CPU 100%解决办法

运行 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/") 函

php进程导致服务器cpu 100问题追查过程

前段时间,出现了一次服务器cpu 占用100的问题.以下为追查原因的过程.仅当抛砖引玉,欢迎拍砖.查看占用cpu高的进程 想找出占用cpu高的进程,用top命令就可以搞定. $top .....此处省略n多行... 10434 root 20 0 509m 174m 1528 R 99.7 0.5 8:42.43 php 5638 root 20 0 509m 174m 1528 R 99.1 0.5 9:12.35 php 16390 root 20 0 541m 182m 5244 R 98

MySQL服务器进程CPU占用100%的解决方法_Mysql

朋友主机(Windows 2003 + IIS + PHP + MYSQL )近来 MySQL 服务进程 (mysqld-nt.exe) CPU 占用率总为 100% 高居不下.此主机有10个左右的 database, 分别给十个网站调用.据朋友测试,导致 mysqld-nt.exe cpu 占用奇高的是网站A,一旦在 IIS 中将此网站停止服务,CPU 占用就降下来了.一启用,则马上上升. MYSQL CPU 占用 100% 的解决过程 今天早上仔细检查了一下.目前此网站的七日平均日 IP 为

dllhost.exe是什么进程?dllhost.exe进程占cpu 100%

dllhost.exe是什么进程 dllhost.exe是微软Windows操作系统的一部分.dllhost.exe用于管理DLL应用.这个程序对你系统的正常运行是非常重要的.  进程信息进程文件: dllhost 或者 dllhost.exe[1]出品者:Microsoft Corp 系统进程:是 后台程序:是 使用网络:否 硬件相关:否 常见错误:未知N/A 常见错误:未知N/A 安全等级 (0-5): 0 间谍软件:否 内存大小:3664k 广告软件:否 病毒:否 木马:否 dllhost

linux php-cgi.exe占用cpu 100%的一次排障之旅_Linux

先说下我们网站的架构,由于目前网站访问量不是很大,但是由于最近公司网站要推广,所以将网站由单机切换成前端用nginx做负载均衡,带动两台web服务器,所有网页和静态文件都通过NFS共享调用,NFS服务装在其中的一个web服务器上,后端用mysql主从的方式,是很典型的架构. 切换成这个架构才2天,就收到nagios的报警,报警信息显示有一台web服务器负载很高,于是通过SecureCRT登录到服务器上,用top命令看了一下,发现有几个php-cgi进程占用了大量的CPU,如下: 13889 ww

服务器-mysql 占用cpu 100%

问题描述 mysql 占用cpu 100% 我的服务器配置是2核 2g的 Linux系统,安装一个淘宝客系统,这个可以采集淘宝商品,一开始采集还可以,但是当数据表里面数量达到17万以上的时候,就显得特别慢,因为他在采集的时候 要查询这个东西是不是已经被采集过,应该去每采集一次就会扫表一次,,mysql进程占用 cpu 98%以上.我不相信是服务器配置不够所照成的,因为2核2g这个配置并不是很低,而且还是Linux系统,如果17w数据都带不动,那么Linux比Windows强不了多少,还不如Win

【原创】CPU 100%+磁盘写满 问题排查

情景:测试人员在进行 RabbitMQ 服务器问题排查时,进行了各种重启操作,之后突然发现机器变的很卡. 排查过程:  1.通过 top 查看,发现名为 sa 的进程 CPU 占用率几乎 100% . 2.查看 sa 进程中哪个线程占用 CPU 比较高  ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [root@rmq_2 ~]# top -Hp 1362 top - 05:36:26 u