六、性能测试之CPU分析与实战

性能测试之CPU分析

      • 一、回顾:性能测试分析的思路
      • 二、cpu知识
        • 1、影响cpu性能的物理因素:架构、主频、核
        • 2、结构:主要物理结构是3个,实际是有4个
        • 3、内存
        • 说人话(总结)
        • 4、内核&线程&架构
        • 5、查看cpu信息
          • 1、`top`
          • 2、`lscpu`
          • 3、`cat /proc/cpuinfo`
        • 6、监控cpu
          • cpu 分析:
          • load average值和cpu使用率之间的关系
          • 上下文
          • cpu性能分析:load高 && cpu高
          • 做性能测试时候每次的结果都相差很大/不准,怎么分析?
      • 三、cpu实战
        • 1、测试前准备
          • 1、查看loadaverage是否正常
          • 2、安装监控
          • 3、模拟压测环境
        • 2、实操
          • 1、模拟进程上下文切换
          • 总结
          • 分析思路
          • 2、模拟线程上下文切换
          • 总结
          • 3、模拟IO密集型
          • 分析思路
          • 解决方案
      • 四、性能测试如何定位到具体代码
      • 五、高频面试题
        • 1、性能测试监控到cpu使用率很高,如何定位问题?
        • 2、性能测试服务器很卡,但是资源利用率不高,如何定位?
        • 3、性能测试出现内存泄露,如何定位?
        • 4、性能测试前期正常,后期报错,怎么分析?
        • 5、性能测试tps上不去,但是cpu资源使用率不高,怎么分析?

一、回顾:性能测试分析的思路

  • 性能测试分析的思路:先分析硬件 、网络、 系统配置、应用程序
  • 硬件: cpu、内存、磁盘、网络、io
  • 本次我们就来谈谈cpu

二、cpu知识

  • cpu:中央处理器(central processing unit)

    • 1、影响cpu性能的物理因素:架构、主频、核
      • 架构:intel(x86),AMD(powerPC),ARM(ARM)
      • 主频:GHz(值越高每秒刷新速度越快)
      • 核心数:
    • 2、结构:主要物理结构是3个,实际是有4个

    六、性能测试之CPU分析与实战_第1张图片

    • 运算器: 真正进行计算的单元
    • 控制器: leader,把内存的指令,数据读入寄存器,控制计算机
    • 寄存器: 暂存指令、数据、地址
    • 时钟:计时
    • 3、内存
      • 程序代码、网络数据,外部数据进入cpu的桥梁,内存的速度,要比cpu的速度慢
    • 说人话(总结)

      一段程序要被执行,先编译成机器语言,进入内存。cpu控制器再从内存中获取指令,数据,放入寄存器中。时钟控制cpu的运算器什么时候开始计算,计算多久。运算器开始计算。运算过程中,如果还需要数据,控制器就从寄存器中拿数据,拿不到就从内存中拿。如果1个时间片段计算不完,就先干其他事,之后再执行。执行完了,输出数据给寄存器,传给内存–> 切换,中断

    • 4、内核&线程&架构
      • 内核:医院的医生,治疗病人
      • 线程:医院的护士,接待病人
        • 线程是cpu调度和反派的基本单位
      • 1医生对1护士:单核单线程
      • 1医生对 n个护士:单核多线程,超频
        • 如何配置超频?
          • 需要手动改配置参数
        • 一般情况下企业都不会使用超频,超频就代表超负荷运行,发热过快,功耗高的时候容易出问题
      • 架构:医院的楼层结构和医疗基础设施
        • 基础越合理,工作效率越高
    • 5、查看cpu信息
      • 1、top

      六、性能测试之CPU分析与实战_第2张图片

      • 2、lscpu

      六、性能测试之CPU分析与实战_第3张图片

      • 对应的说明
        六、性能测试之CPU分析与实战_第4张图片
      • 3、cat /proc/cpuinfo
        • 内存中记录的cpu信息(这边展示的是每个cpu的单独信息,非统计的)
        • /proc 虚拟文件,操作系统启动时,读取的信息,这些信息放内存中
        • cpu想要改成超频的,就是这里改了
          六、性能测试之CPU分析与实战_第5张图片
    • 其他的常用命令

      • cat /proc/cpuinfo |grep "physical id" |sort |uniq |wc -l 查看物理cpu数量

      • cat /proc/cpuinfo | grep "cpu cores" |uniq 查看CPU的core数,即核数

      • cat /proc/cpuinfo | grep "processor" |wc -l 查看逻辑CPU数量

      • load average = cpuload + ioload

  • 6、监控cpu
    • cpu 分析:
      • us:用户进程空间中未改变过优先级的进程占用cpu百分比(程序在cpu进行计算的时候,没有改变过优先级,没有成为内核进行计算,在非内核计算的时间)
        • 用户运行计算–>cpu密集计算 or FGC or 死循环
          • cpu密集计算:代码逻辑很复杂,可能计算时候要进行密集的逻辑判断,这时候会消耗us态的时间
          • FGC:
            • GC:资源回收
            • FGC:(Full GC)对老年代的资源进行回收。程序运行起来会分配内存资源,如果资源一直用的上,那就一直放在内存里,然后不用了再进行回收。这种回收消耗时间较长。资源回收就会带来中断和卡顿,卡顿也会导致程序暂时无响应(卡顿时间是毫秒级)
            • YGC:(Young/Minor GC)新生代资源回收:资源用一次就不用了,把资源释放
          • 死循环:一直在计算,用户态死循环就会占用很长时间
      • sy:内核空间占用cpu百分比。
        • 做上下文切换(自愿上下文切换,非自愿上下文切换)
          • 上下文切换:寄存器里的资源进行切换
          • 自愿上下文切换 --> 内存瓶颈
            • 举例:比如进行计算时候,有10个程序,第一个程序有连续5个指令,但是在执行第三个指令的时候因为资源不够,要等待,那就切换其他进程处理其他指令。(资源不够,自觉切换到另外的指令)
          • 非自愿上下文切换 -->cpu瓶颈
            • 举例:执行第三个指令的时候,时间到了,这时候没有执行完,被迫中断/时间有,但是来了个优先级更高的,要立刻执行,强制中断。如果cpu够多,那就可以用另外的cpu去处理,所以是cpu瓶颈(有可能有优先级更高的指令,指令执行的时间已经到了,被迫中止当前的指令,去执行其他指令)
      • ni:用户进程空间内改变过优先级的进程占用cpu百分比(内核->非内核,或非内核->内核切换所用时间)
        • 用户运行计算–>cpu密集计算 or FGC or 死循环
      • id:空闲时间百分比
      • wa:空闲&等待IO的时间百分比(很多时候是资源不够导致的等待)
        • 等待资源 --> IO问题(磁盘/网络)
      • hi:硬中断时间百分比(程序中断导致的切换(比如时间片到了))
      • si:软中断时间百分比(自愿进行切换)
        • 软中断 -->cpu竞争抢资源 or 资源不够IO问题
      • st:虚拟化时被其余vm窃取时间百分比
        • 抢占资源 --> 宿主机抢占资源
    • load average值和cpu使用率之间的关系
      • 现在的linux服务器中,load average不等于cpu使用率
      • load average是系统的整体负载体现
        • 它包括 cpu负载+disk负载+网络负载+外设负载
        • loadaverage=cpuload+ioload(disk+网络+外设负载都是io负载)
      • cpu的使用:用户进程使用的时间us,系统内核运行时间sy,空闲时间idle,管理被抢占时间st
        • 繁忙:us+sy+st+ni+hi+si cpu使用率的时间(除以总时间)
        • 空间:idle+wa
      • 上下文
        • 上下文:cpu寄存器和程序计数器

          • 程序计数器:存储cpu正在执行的指令位置和下一条指令的位置
            六、性能测试之CPU分析与实战_第6张图片
        • 上下文切换:先把当前任务的cpu上下文(cpu寄存器和程序计数器)保存起来(内核中),然后加载新任务的上下文到cpu的寄存器和程序计数器中,cpu再跳转到程序计数器上执行新任务)

        • 上下文切换类型:进程上下文切换,线程上下文切换,中断上下文切换

          • 进程:资源的基本单位
          • 线程:调度的基本单位
        • 进程上下文切换

          • 特权等级,跨等级时,需要系统调用:
            • 同进程上下文切换:进程用户态-- 系统调用–>进程内核态–系统调用–>进程用户态
            • 不同进程上下文切换:进程切换时要保存用户态资源(虚拟内存,栈等)
        • 线程上下文切换

          • 线程,共享进程的资源,但是,线程也有自己的所有数据,如栈,寄存器
          • 同进程中线程上下文切换:进程资源共享,切换线程私有资源
          • 好比,同一个公司,不同部门之间交流;同公司不同楼层交流
        • 不同进程中线程上下文切换:切换进程

    • cpu性能分析:load高 && cpu高
      • top
        • 情况1:sys系统态高 --> 需要排查cpu上下文切换
          • 如果非自愿上下文切换多,说明cpu不够用,进程时间片刻,被迫切换
          • 如果自愿上下文切换多,说明计算用的资源不够用,可能存在IO,内存瓶颈
        • 情况2:si软中断高 --> cpu抢资源,资源不够用IO问题
          • sys高+si高 --> 推导出:内存 or网络IO问题 --> 解决方法:排查内存和IO
          • sys高+si不高 --> 推导出:cpu瓶颈 --> 解决方法之一 :加cpu
        • 情况3:us用户态高 --> 用户程序计算
          • 密集型计算,内存FGC,资源等等(线程池)–>解决方法:逐个排查
    • 做性能测试时候每次的结果都相差很大/不准,怎么分析?
      • 如果是用无线网络测试的,可能会出现数据传输不稳定,出现延迟,导致结果会出现较大出入。我们就需要监控网络情况。有以下几种方式:
        • 1,jmeter聚合报告最后两列,可以利用这两个值计算出带宽。企业可能用千兆光纤,但是企业的服务器一般只有几兆到几十兆。
        • 2,也可以通过监控方式,如果有云服务器的管理台,可以看下管理台的网络流量图。
        • 3,直接ping被测服务域名/ip,看看网络的延迟时间。如果时间在几毫秒~几十毫秒以内,那是可以接受的。我们可以在没有做测试前可以ping一下,正在做测试过程中也ping一下,看看有没有明显增大,如果增大非常多,甚至出现丢包,那就说明延迟已经影响性能测试,网络已经成为瓶颈。

    三、cpu实战

    • 1、测试前准备
      • 1、查看loadaverage是否正常
        • 真正在做性能测试时,你要管理好你的被测服务器,loadaverage要恢复正常,第一个值,没有明显的上升或下降的趋势,也就是说第1个值要基本不变。
      • 2、安装监控
        • 这里用的grafana+prometheus + 硬件资源\应用资源(详情可以去看我另外一篇博客)
        • 服务器硬件资源监控: grafana(前端) + prometheus(时序数据库) + node_exporter(硬件资源收集器)
        • 被测服务器上 部署 node_exporter
        • node_exporter上传到被测服务器
        • 解压、启动 ./node_exporter
        • 端口:9100
        • 监控平台机器上,启动 grafana + prometheus
        • 进入prometheus文件夹,修改Prometheus.yml的配置文件
        • 保存好配置文件,启动Prometheus ./prometheus 默认端口:9090
        • 启动grafana systemctl restat grafana-server 默认端口: 3000
        • http://grafanan_ip:3000 admin admin
      • 3、模拟压测环境
        • 这次我们用的是模拟压测的工具stress-ng进行压测,它可以直接模拟服务器各种压力情况(cpu,磁盘,io)
        • 安装:
          • 1、安装epel源,更新系统yum install -y epel-release.noarch && yum -y update
          • 2、安装stess-ng 的工具 yum install -y stress-ng
    • 2、实操
      • 1、模拟进程上下文切换
(( proc_cnt = `nproc`*10 )); stress-ng --cpu $proc_cnt --pthread 1 --timeout 150
# nproc   这个命令可以获得服务器cpu的数量
# (( proc_cnt = `nproc`*10 ));   把cpu核的数量乘以10倍,给变量proc_cnt
# --cpu $proc_cnt  $proc_cnt shell编程中的变量引用
# --pthread  每个进程有多少个线程
# --timeout   超时时间,在命令执行多长时间之后自动结束
  • 压测前:
    六、性能测试之CPU分析与实战_第7张图片

  • 我们开始压测:
    六、性能测试之CPU分析与实战_第8张图片
    再看top命令,loadaverage,task,cpu的us,sy明显增大了
    六、性能测试之CPU分析与实战_第9张图片

  • 查看vmstat 1
    六、性能测试之CPU分析与实战_第10张图片

  • 查看 pidstat -w 1
    六、性能测试之CPU分析与实战_第11张图片

  • 结束后,数据慢慢降下来
    六、性能测试之CPU分析与实战_第12张图片

  • 查看grafana监控平台
    六、性能测试之CPU分析与实战_第13张图片

总结
  • 1、top命令,可以到 loadaverage 有持续上升,cpu被100%使用 us + sy + si

  • 2、 vmstat proc中r列有非常大的数据 有非常多的进程在抢cpu的资源

    • memory: free 数据变小, 内存有一部分被使用、
    • system: in有一点点, cs 有明显数据变大,说明有大量的 上下文切换
  • 3、 pidstat -w 1----这个命令可以上下文的信息。我们看到的大量 stress-ng–cpu cswch/s 自愿和nvcswch/s非自愿上下文的值。现在可以得出 ,我们线程有大量的 进程上下文切换问题,而这个问题的进程:stress-ng–cpu。

分析思路

1、首先我们使用top命令发现服务器的系统负载比较高,所有的cpu的使用率接近或等于 100%,我们要排查这个问题。
2、我们使用vmstat 1命令,发现procs 中r列有大量数据,说明我们有大量进程在竞争cpu的资源。可能服务器的cpu数量不够, 也可能是进程启动的太多导致。我们还看system中cs比较高,表示肯定有大量的上下文切换。但是此时我们并不知道是哪个进程导致 抢占cpu,我们需要找出具体是哪个进程。应该是某个经常有大量的上下文切换,而导致的cpu使用率过高,系统负载过高的问题。
3、接着我们使用pidstat -w 3命令,看到具体的上下文切换的数据比较大的进程,得到具体进程 和进程id:stress-ng–cpu

  • 2、模拟线程上下文切换
# 该命令会在n个cpu核的系统上,产生n个线程,模拟线程间竞争cpu的场景
stress-ng --cpu `nproc` --pthread 1024 --timeout 60
  • 分析命令:
    • top
    • vmstat 1
    • pidstat -w 5
  • 结果如下
    六、性能测试之CPU分析与实战_第14张图片
    六、性能测试之CPU分析与实战_第15张图片
总结
  • 1、top: load值一直在增加,而且增长的非常大

  • 2、top:CPU的 us + sy ≈ 100%,us较低,sy较高

  • 3、vmstat: procs的r 就绪队列长度,正在运行和等待的CPU进程数很大

  • 4、vmstat: system的in(每秒中断次数) 和 cs(上下文切换次数) 都很大

  • 5、vmstat:free变小、buff基本不变、cache变大

  • 6、pidstat: cswch/s 自愿上下文切换 升高

    • 3、模拟IO密集型
      • IO不要再理解为:读写操作,换入换出
      • IO密集型,导致服务器平均负载比较高
      # 读命令会开启一个worker不停地读写临时文件,同事启动6个workers不停地调用sync系统提交缓存
        stress-ng  -i 6 --hdd 1 --timeout 150
      
分析思路
  • 首先我们使用top命令进行分析,得出如下结论:
    • loadaverage 上升
    • cpu: wa值很大 us、sy不是很大, buff/cache有增大
  • 然后我们使用vmstat进行分析(vmstat 1),得出如下结论:
    • mem free减少, cache有明显的增大,bo有明显数据,说明有大量磁盘数据交换
  • 然后我们再使用mpstat -P ALL 3进行分析,发现 %iowat 数值比较大,再次证明,我们线程系统负载比较高的原因是系统的磁盘读写测试性能瓶颈,那到底是哪个进程导致我们的磁盘读写高?我们使用pidstat -w 1命令,发现stress-ng-hdd这个进程的自愿上下文切换数据比较大
解决方案
  • 换磁盘
  • 迁移到io性能更好的服务器。如果你是整体的迁移你的数据库,这个风险比较大,我们可以再另外一个IO性能比较好服务器,再安装一个数据库,做数据库的读写分离
  • 减少io操作(有的时候日志打多了会造成这样的情况,可以调高日志的级别)

四、性能测试如何定位到具体代码

思路:具体进程id之后, 找到进程线程id,然后把线程id进行16进制转换, 进程id日志打印出来,过滤出线程id(16进程),后面会详细讲解

五、高频面试题

1、性能测试监控到cpu使用率很高,如何定位问题?

答:我们可以通过top,vmstat,pidstat命令进行定位
1、通过top命令判断是用户态还是系统态问题
六、性能测试之CPU分析与实战_第16张图片
2、通过vmstat定位process是r还是b列
六、性能测试之CPU分析与实战_第17张图片
3、通过pidstat具体看是自愿上下文还是非自愿上下文,看到具体的上下文切换的数据比较大的进程

2、性能测试服务器很卡,但是资源利用率不高,如何定位?

答:top命令查看wa的值是不是比较高,是的话说明有IO问题,我们再用iostat查看具体是哪一块导致的

3、性能测试出现内存泄露,如何定位?

答:通过jmap或者arthas来dump下内存的信息,通过MAT分析工具定位到代码问题,给开发人员看

4、性能测试前期正常,后期报错,怎么分析?

答:1、看报错信息,可能是网络堵塞
2、看系统负载是否恢复正常再开始测试
3、源端口是否够用
4、根据报错信息,具体分析

5、性能测试tps上不去,但是cpu资源使用率不高,怎么分析?

答:可能是以下的有问题

  • 网络带宽
  • io
  • 连接池:应用连接池、数据库连接池过小,默认151
  • 资源没有及时回收: gc、堆栈配置
  • 数据库的配置:比如报错too many connections
  • linux服务器的配置
  • 通信连接机制:websocket协议比http协议性能好很多
  • 硬件:内存太小,网卡速度太慢
  • 脚本本身有问题:比如脚本加了beanshell
  • 压力机太少,可以使用分布式
  • 业务逻辑:比如被测服务器业务逻辑复杂,性能本身就比较差
  • 系统架构:把代码写在一个地方肯定比不上拆分成微服务

你可能感兴趣的:(性能测试,jmeter,性能测试,监控,linux,运维)