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

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

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

二、cpu知识

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

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

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

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

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

      在这里插入图片描述

      • 2、lscpu

      在这里插入图片描述

      • 对应的说明
        在这里插入图片描述
      • 3、cat /proc/cpuinfo
        • 内存中记录的cpu信息(这边展示的是每个cpu的单独信息,非统计的)
        • /proc 虚拟文件,操作系统启动时,读取的信息,这些信息放内存中
        • cpu想要改成超频的,就是这里改了
          在这里插入图片描述
    • 其他的常用命令

      • 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上下文(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   超时时间,在命令执行多长时间之后自动结束
  • 压测前:
    在这里插入图片描述

  • 我们开始压测:
    在这里插入图片描述
    再看top命令,loadaverage,task,cpu的us,sy明显增大了
    在这里插入图片描述

  • 查看vmstat 1
    在这里插入图片描述

  • 查看 pidstat -w 1
    在这里插入图片描述

  • 结束后,数据慢慢降下来
    在这里插入图片描述

  • 查看grafana监控平台
    在这里插入图片描述

总结
  • 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
  • 结果如下
    在这里插入图片描述
    在这里插入图片描述
总结
  • 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命令判断是用户态还是系统态问题
在这里插入图片描述
2、通过vmstat定位process是r还是b列
在这里插入图片描述
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
  • 压力机太少,可以使用分布式
  • 业务逻辑:比如被测服务器业务逻辑复杂,性能本身就比较差
  • 系统架构:把代码写在一个地方肯定比不上拆分成微服务
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 目标场景和需求分析 在进行性能测试之前,需要明确测试的目标场景和需求,包括: - 测试的业务场景和流程 - 测试的并发用户数和请求量 - 系统的性能指标和要求 例如,假设要测试一个电商网站的性能,需要关注以下几个方面: - 用户登录 - 商品搜索 - 商品浏览和详情页 - 下单和支付 同时,需要考虑并发用户数和请求量,以及系统的性能指标和要求,例如: - 并发用户数:1000 - 请求量:每秒1000次 - 响应时间:平均在3秒以内,99%的请求在5秒以内完成 2. 准备测试环境 在进行性能测试之前,需要准备好测试环境,包括: - 测试服务器:部署被测试系统的服务器 - 压力机:用于模拟并发请求的机器 - 测试工具:例如JMeter,用于进行性能测试 在准备测试环境时,需要注意以下几个方面: - 测试服务器的配置应该与生产环境尽可能接近,包括硬件配置和软件版本等。 - 压力机的数量和配置应该根据测试需求和目标场景进行调整,确保能够模拟真实的并发请求。 - 测试工具的配置应该根据测试需求和目标场景进行调整,例如线程数、请求间隔、请求参数等。 3. 编写测试脚本 在JMeter中,可以通过录制脚本或手动编写脚本的方式进行性能测试。以下是手动编写脚本的步骤: - 添加线程组:在JMeter中,线程组用于模拟并发用户,需要设置线程数、循环次数、启动延迟等参数。 - 添加HTTP请求:在线程组中添加HTTP请求,需要设置请求的URL、请求方法、请求参数等。 - 添加断言:可以通过添加断言来验证请求的响应结果是否正确,例如判断响应码、响应内容等。 - 添加监听器:可以通过添加监听器来收集和分析测试结果,例如查看响应时间、吞吐量、错误率等指标。 4. 进行性能测试 在编写完测试脚本后,可以通过以下步骤进行性能测试: - 配置测试计划:在JMeter中,可以配置测试计划,包括设置测试时长、并发用户数、请求量等参数。 - 启动测试:点击“运行”按钮,JMeter会模拟并发用户发送请求,收集测试结果。 - 监控测试结果:可以通过监听器查看测试结果,例如查看响应时间、吞吐量、错误率等指标。 - 分析测试结果:根据测试结果,可以进行性能优化和调整,例如优化数据库查询、增加服务器的内存和CPU等。 5. 总结和反思 在测试完成后,需要对测试结果进行总结和反思,包括: - 测试目标是否达成 - 测试过程中遇到的问题和解决方法 - 测试结果的分析和总结 - 性能优化和调整的建议 总结和反思可以帮助团队不断改进和优化自己的性能测试方法和流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值