PHP 获取 Linux 系统 CPU 负载的例子
发布:smiling 来源: PHP粉丝网 添加日期:2018-09-17 09:52:10 浏览: 评论:0
最近使用 PHP 做了一个服务器负载监控的小东西,在服务器上使用 Workerman 开一个 WebSocket 服务,然后在浏览器中连接到服务。服务每隔 10 秒读取一次主机的相关信息,然后发送给客户端,客户端进行图形化显示。
总体的思路就是使用 PHP 调用 shell 命令,然后解析命令的输出内容。在获取 CPU 负载的时候,遇到了一些小问题。直观来说,直接使用 vmstat 命令就可以获取 CPU 负载,但是实际上,vmstat 命令第一行输出的从主机启动以来的平均 CPU 负载,并不是当前的负载。vmstat 命令还有一些参数,比如可以增加一个延迟参数 delay: vmstat 1,表示每秒输出一次数据,直到用户终止命令:
- miroot@miserver:~$ vmstat 1
- procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
- r b swpd free buff cache si so bi bo in cs us sy id wa st
- 4 0 0 493644 162940 5727744 0 0 2 15 0 0 1 0 99 0
- 0 4 0 568392 162952 5656868 0 0 112 15584 8807 4496 29 6 57 7
- 3 0 0 567152 162952 5657416 0 0 40 116 10104 5164 28 6 65 2
- 2 1 0 566368 162956 5658476 0 0 84 22220 11126 5632 29 7 58 5
- 2 2 0 563320 162964 5659200 0 0 56 49240 9765 4792 21 7 53 19
- 0 0 0 566464 162976 5659892 0 0 80 1212 9998 5135 26 6 59 9
- 2 0 0 565400 162984 5660736 0 0 92 120 9288 4954 29 5 66 1
- ^C
- miroot@miserver:~$
第一行数据是平均负载,从第二行数据开始,是当前的负载情况。作为监控来讲,肯定更加关注当前的负载情况。
那么,使用 PHP 调用 vmstat,当然不能使用延迟的方式来等待后续行的输出。
查了一些文档,发现在 Linux 上,系统负载的情况在 /proc/stat 这个文件中,这个文件中的内容比较多,所以我们换一个思路,采用 vmstat -s 的方式直接输出内容:
- miroot@miserver:~$ vmstat -s
- 8165768 K total memory
- 4600664 K used memory
- 1980464 K active memory
- 2249908 K inactive memory
- 3565104 K free memory
- 232532 K buffer memory
- 2972048 K swap cache
- 8378364 K total swap
- 253352 K used swap
- 8125012 K free swap
- 1170373 non-nice user cpu ticks
- 25184 nice user cpu ticks
- 294692 system cpu ticks
- 1309152182 idle cpu ticks
- 1867039 IO-wait cpu ticks
- 566 IRQ cpu ticks
- 76405 softirq cpu ticks
- 0 stolen cpu ticks
- 4601555 pages paged in
- 96400000 pages paged out
- 1516 pages swapped in
- 67468 pages swapped out
- 243751059 interrupts
- 384963258 CPU context switches
- 1455419401 boot time
- 184668 forks
- miroot@miserver:~$
可以看到,这里面包含很多和 CPU 相关的数据,实际上这个数据的来源就是 /proc/stat 文件。那么我们关心这么几项数据:
- 1170373 non-nice user cpu ticks
- 25184 nice user cpu ticks
- 294692 system cpu ticks
- 9152182 idle cpu ticks
通过 man 5 proc 找到关于 /proc/stat 文件的说明,我们关心的是 CPU 相关数据的说明:
- The amount of time, measured in units of USER_HZ (1/100ths of a second on most architectures, use sysconf(_SC_CLK_TCK) to obtain the right value), that the system spent in various states:
- user (1) Time spent in user mode.
- nice (2) Time spent in user mode with low priority (nice).
- system (3) Time spent in system mode.
- idle (4) Time spent in the idle task. This value should be USER_HZ times the second entry in the /proc/uptime pseudo-file.
大概的意思就是说,这些数值都是以 USER_HZ 为单位的。不管什么单位,总之他们的单位是一致的,那么我们就可以通过 2 次 vmstat -s 命令的输出来计算每个项上的增量,然后 4 个项上的增量相加就是总体的增量(其实后面还有更多关于 CPU 的数据,我们先忽略掉),然后计算每个项上的增量和总体增量的比,就是在这两次采样之间 CPU 在用户、系统和闲置状态下的负载。
参考代码如下:
- // 在 Linux 系统上,需要使用 2 次 vmstat -s
- // 结果的差值来计算两次采样之间的 CPU 占用比例
- $last_cpu_ticks = array(
- 0, // non-nice user cpu ticks
- 0, // nice user cpu ticks
- 0, // system cpu ticks
- 0 // idle cpu ticks
- );
- function _get_cpu_status_linux()
- {
- global $last_cpu_ticks;
- $s = shell_exec('vmstat -s | grep cpu');
- if ($s === false) return false;
- $lines = explode("n", $s);
- if (count($lines) < 4) return false;
- $current_data = array();
- for ($i = 0; $i < 4; $i++)
- {
- $current_data[] = (int)(explode(' ', trim($lines[$i]))[0]);
- }
- $ret = array('user' => 0, 'sys' => 0, 'idle' => 0);
- if ($last_cpu_ticks[0] > 0)
- {
- $total_delta = 0;
- foreach ($current_data as $i => $v)
- $total_delta += ($v - $last_cpu_ticks[$i]);
- $ret['user'] = (int)(($current_data[0] - $last_cpu_ticks[0] + $current_data[1] - $last_cpu_ticks[1]) / $total_delta * 100);
- $ret['sys'] = (int)(($current_data[2] - $last_cpu_ticks[2]) / $total_delta * 100);
- $ret['idle'] = (int)(($current_data[3] - $last_cpu_ticks[3]) / $total_delta * 100);
- } //phpfensi.com
- for ($i = 0; $i < 4; $i++)
- $last_cpu_ticks[$i] = $current_data[$i];
- return $ret;
- }
Tags: 例子 系统
- 上一篇:PHP变量命名规则详解
- 下一篇:开启PHP的error_log排查线上遇到的错误
相关文章
- ·PHP实现提交表单及输出例子(2014-06-10)
- ·php中英文字符串长度截取的例子(2014-06-28)
- ·PHP验证码生成与验证例子(2014-08-22)
- ·php提取字符串里所有URL的例子(2015-12-10)
- ·PHP中data/base64数据流转图片文件输出例子(2017-03-23)
- ·微信公众号开发者模式普通消息模式例子(2017-03-23)
- ·php error_log 错误信息写入文件的例子(2017-03-23)
- ·php数组编码的转换方式的例子(2017-03-23)
- ·PHP中data/base64数据流转图片文件输出例子(2017-03-23)
- ·php准确校验邮箱地址是否存在的例子(2017-03-23)
- ·PHP七种不同的个性创意验证码例子(2017-03-23)
- ·PHP输出缓冲及其应用的例子(2018-05-31)
- ·php 去重累加的例子(2018-05-31)
- ·php怎么写网页?php写网页简单的例子(2018-07-12)
- ·Yii添加百度编辑器 ueditor 扩展例子(2018-09-15)
- ·PHP记住密码功能实现例子(2018-09-16)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)