首页 > 其他分享 >ps vs top:CPU占用率统计的两种不同方式

ps vs top:CPU占用率统计的两种不同方式

时间:2023-05-23 20:46:52浏览次数:63  
标签:ps top time 占用率 CPU 统计

如何计算 CPU 占用率?

简单来说,进程的 CPU 占用率指的是 CPU 有多少时间花费在了运行进程上。在 Linux 系统里,进程运行的时间是以jiffies[1]统计的,通过计算jiffies * HZ,就可以得到进程消耗的 CPU 时间,再除以 CPU 的总时间,就可以得到进程的 CPU 占用率:jiffies * HZ / total_time

ps 和 top 的不同之处

pstop是最常用的两种查看 CPU 占用的方式,都可以用来快速找到当前 CPU 占用率高的进程。但实际上这两个工具的统计方式是完全不同的。

我们用下面这个简单的 Go 程序来测试这两个工具的差别:

package main

import (
	"bytes"
	"fmt"
	"strconv"
	"sync"
	"time"
)

var testData = []byte(`testdata`)

func testBuffer(idx int) {
  m := map[string]*bytes.Buffer{}
  for i := 0; i < 100; i += 1 {
    buf, ok := m[strconv.Itoa(i)]
    if !ok {
      buf = new(bytes.Buffer)
    }
    for j := 0; j < 1024; j += 1 {
      buf.Write(testData)
    }
    m[strconv.Itoa(i)] = buf
  }
  fmt.Println("done, ", idx)
  wg.Done()
}

var wg sync.WaitGroup

func main() {
	for i := 0; i < 10; i += 1 {
		wg.Add(1)
		j := i
		go testBuffer(j)
	}
	wg.Wait()
	fmt.Println("sleeping")
	time.Sleep(time.Hour)
}

然后我们运行这个程序,通过topps aux分别查看进程的 CPU 占用情况。

top -n 1:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
39753 infini    20   0 14.663g 0.014t   1200 S 611.1 22.2   0:23.53 test-cpu

ps aux:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
infini   39881  767 39.1 26505284 25791892 pts/16 Sl+ 07:04   0:38 ./test-cpu

可以看到,pstop统计的 CPU 占用率是近似的(由于时间点并不完全吻合,统计值也会有轻微差别)。两个工具的差异体现在testBuffer结束后,top统计的 CPU 占用率已经接近于 0,但是ps依然统计到很高的 CPU 占用率:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
infini   39881 82.3 42.4 28638148 27953532 pts/16 Sl+ 07:04   0:40 ./test-cpu

为什么 ps 和 top 的统计值会有差异?

这两个工具的差异来自于各自运行方式的不同:top 只能持续运行一段时间,而 ps 是立刻返回的。这个差异体现在运行top -n 1ps aux时,top是延迟后返回的,而ps是立刻返回的。这两种不同的运行方式就会反映在两个工具的统计算法上。

文章开头我们提到,Linux 的 CPU 时间是按照jiffies统计的,考虑到效率问题,Linux 只会统计总值,不会记录历史数据。对于 ps 来说,由于只能统计到瞬时值,这个瞬时值的统计算法就必然拿不到实时的 CPU 占用率,因为实时的占用率需要通过 (current_cpu_time - last_cpu_time) / time_duration来得到,ps 只能统计一次,所以time_duration0,也就无法计算这个占用率。实际上,ps 统计的是整个进程运行周期内的 CPU 占用率[2]:

(total_cpu_time / total_process_uptime)

对于测试程序这种短时间的占用率上升,刚开始的时候 ps 能够统计到近似准确的平均 CPU 占用率,但是 cpu 占用恢复后,ps 的统计值并不会立刻下降,而是会随着进程运行时间total_process_uptime的增加缓慢下降。

top 命令不同, top 是通过持续运行来更新 CPU 占用率统计的。-n 1这个参数指定 top 运行一个迭代后退出,top命令就可以通过这个延迟来可以完成一个迭代内的 CPU 占用率统计:

(current_cpu_time - last_cpu_time) / iteration_duration

如何持续监控 CPU 占用率?

通常来说,监控系统分为采集和统计两个不同的组件,采集组件只会采集指标数值,统计功能通过数据库/Dashboard 来实现。要监控 CPU 占用率,ps是一个非常符合采集组件行为的统计方式,每次采集都可以拿到“当前”的 CPU 占用率。但是受限于算法本身的统计方式,我们实际采集到的是平均 CPU 占用率,无法反映进程的实时状态。

以 INFINI Console为例,我们运行一个短时间的数据迁移任务负载,然后查看对应 INFINI 网关实例的 CPU 占用监控(payload.instance.system.cpu,通过ps方式统计当前 CPU 占用率)。可以看到,CPU 占用率会以一个曲线上升,在任务结束后会缓慢下降:

如果想持续监控实时 CPU 占用率,我们就需要借鉴top的统计方式,采集原始的进程 CPU 时间,进而通过聚合数据来计算 CPU 占用率。

在 Linux 系统下,pstop命令都会通过/proc/[PID]/stat提供的信息来计算 CPU 占用率[2]:

##  Name      Description
14  utime     CPU time spent in user code, measured in jiffies
15  stime     CPU time spent in kernel code, measured in jiffies
16  cutime    CPU time spent in user code, including time from children
17  cstime    CPU time spent in kernel code, including time from children

获取到每个采样时间的进程信息后,我们就可以通过这个公式来计算采样周期内的 CPU 占用率:

delta(cpu_time) / delta(timestamp)

在 INFINI Console,我们可以通过deriative函数来计算payload.instance.system.user_in_mspayload.instance.system.sys_in_ms相对于timestamp的占比,进而得到准确的 CPU 占用率统计。

New utilization algorithm configuration in Console

这样,我们就可以统计到网关在运行任务负载前后的实时 CPU 占用率:

New utilization algorithm

总结

虽然topps都可以统计 CPU 占用率,但统计算法却完全不同。了解这两种算法的底层原理之后,我们就可以设计出适合监控系统的数据采集和数据统计方式,采集到准确的 CPU 占用率。

参考

  1. Jiffies
  2. Top and ps not showing the same cpu result

标签:ps,top,time,占用率,CPU,统计
From: https://www.cnblogs.com/infinilabs/p/17426314.html

相关文章

  • [AndroidTips]Tablet不断重启原因分析
    现象:启动后,可以进入主界面。但是过几分钟自动重启。以后不断重复此现象。分析:1、手机如果重启,会在/data/system/dropbox留下开机信息,可以查看次类文件生成的时间标来了解手机重启的时间情况。另外,系统会自动记录最后一次开机/重启的原因到/proc/bootinfo。 2、查看bootinfo,可以......
  • ​https网址放在浏览器上访问,​https后面的冒号:消失不见,并且访问失败
    由于地址前面多了一个看不见的符号%E2%80%8B,这个特殊符号叫Zero-width-space(零宽空格),它是一个Unicode字符,肉眼不可见,却是确实存在的一个字符。使用encodeURI 编码可以发现从swagger文档复制,字符就可能存在%E2%80%8B,可以把地址前面的http://拼接上baidu.com放浏览器搜索,查看请......
  • mac的截图及sips使用心得
    1-mac推荐截图工具从ubuntu切换到Mac,最放不下手的其实是一个叫flameshot的截图工具,确实是ubuntu系统的神器,但是渐渐熟悉mac后发现mac才是各种大杀器的集合地,今天想谈到的就是截图工具,初接触mac的时候,几乎接触了mac大多数别人推荐的截图工具,如下所示:系统截图工具;微信截图工具;浏览器......
  • AppScan
    AppScan 工具介绍:AppScanStandard是一种动态分析工具,通过使用类似于黑客使用的方法的技术攻击应用程序来评估运行时的应用程序安全性。测试结果包括一组丰富的数据,从应用程序清单到详细的攻击流量,这些数据可以重现以进行验证和修复。这些数据可以在UI界面中检查和处理,也可以......
  • TPSO-DSDT粒子群算法在三维装箱问题上的应用
    组合算法是将传统启发式算法与数学规划算法结合元启发式算法共同工作进行相应的计算,还有融合多种算法所获得的计算方法,结合了所有算法自身的有点,规避其自身缺点从而达到解决装箱问题的最终目的。现在,组合算法的整体规划绝大多数都是通过启发式算法完成的,局部优化的过程采用的是人......
  • PHP用PhpOffice->PhpSpreadsheet导出excel
    phpexcel由于版本陈旧性能低下官方放弃维护转而开发PhpSpreadsheet用了最新得psr标准因而对php版本不向下兼容需要注意!。PhpSpreadsheet是一个用纯PHP编写的库,提供了一组类,使您可以读取和写入不同的电子表格文件格式PhpSpreadsheet提供了丰富的API接口,可以设置诸多单元格以及文......
  • BurpSuite证书安装
    一、要拦截HTTPS的请求就必须安装SSL证书二、BurpSuite设置proxy代理三、浏览器上设置代理,Chrome使用CTRL+SHIFT+Delete打开设置界面,搜索关键字“代理”,端口号必须与BurpSuite上设置的端口号一致四、访问本机:http://127.0.0.1:8081/,下载证书五、安装证书双击cac......
  • https部署与docker下nginx的转发+文件获取
    进入nginx容器查看是否有etc/nginx/cert目录将https的域名证书放到cert目录下配置80和443server{#listen80;#侦听80端口listen80;#侦听443端口,用于SSLserver_name127.zyfdtsite.com;client_max_body_size1024m;#charsetkoi8-r;#acc......
  • 基于PSO优化的SVM数据预测算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要         支持向量机(supportvectormachines,SVM)是二分类算法,所谓二分类即把具有多个特性(属性)的数据分为两类,目前主流机器学习算法中,神经网络等其他机器学习模型已经能很好完成二分......
  • ADG级联备库环境PSU应用验证
    上篇文章源端为备库的场景下Duplicate失败问题我只在中间备库环境应用了PSU,解决了级联备库从中间备库duplicate数据库的问题:细心的朋友已经发现,因为是备库环境,并没有做数据库执行相关脚本部分,所以如果去DB查询补丁应用信息是没有的:SQL>r1*select*fromdba_registry_......