• 性能测试-性能监控分析与调优(三)《实战》


    性能监控

    使用命令监控

    cpu瓶颈分析
    top命令

    在进行性能测试时使用top命令,界面如下
    在这里插入图片描述

    上图可以看出

    • CPU 概况区: %Cpu(s):
      • us(用户进程占用CPU的百分比), 和 sy(系统进程占用CPU的百分比) 的数值很高说明cpu处于忙碌状态,
      • 且id(空闲CPU百分比)的值也比较高说明cpu的资源还比较足。
      • si(软件中断所消耗的CPU使用的百分比)只占用一点点

    load average(负载平均值): 显示了1分钟、5分钟、15分钟的平均负载值。可以看出最近1分钟内发生了大量的负载

    物理内存(Mem)和交换空间(Swap):

    • total:物理内存的总大小。
    • used:已使用的物理内存大小。
    • free:剩余的物理内存大小。
    • buff/cached:缓存的物理内存的大小占比

    CPU使用率排序显示进程列表:

    • PID:进程ID,表示每个进程的唯一标识符。

    根据上面进行分析可以得出改系统进行性能测试时,可以看出us比sy高很多,且cpu使用率排在前面的应用程序主要为java程序和数据库mysql
    用户态比较高:
    %us (或 %user):
    这个参数表示 CPU 在用户态下执行应用程序代码的时间比例。如果这个值较高,说明用户态时间比例较高。

    %id (或 %idle):
    这个参数表示 CPU 空闲的时间比例。如果用户态时间比例高,通常 %id 的值会比较低,因为 CPU 没有太多空闲时间。

    CPU 使用率:
    在 top 命令的顶部,会显示总的 CPU 使用率,包括用户态、系统态、空闲等。如果用户态时间比例高,总的 CPU 使用率也会相应较高。

    进程列表:
    在 top 命令的进程列表中,可以看到每个进程的 CPU 使用情况,包括用户态和系统态时间。如果某个进程的用户态时间比例较高,可能需要进一步分析该进程的行为。

    java程序也就是应用程序,它的使用率高,说明它的代码消耗的cpu比较多,需要分析代码问题 详见 > 分析定位代码问题

    数据库服务器cpu用户态高:说明是 sql语句的逻辑很复杂。 sql要分析优化。

    系统态比较高
    %sy (或 %system):
    这个参数表示 CPU 在内核态下执行系统代码的时间比例。如果这个值较高,说明系统态时间比例较高。

    %id (或 %idle):
    这个参数表示 CPU 空闲的时间比例。如果系统态时间比例高,通常 %id 的值会比较低,因为 CPU 没有太多空闲时间。

    %wa (或 %iowait):
    这个参数表示 CPU 等待 I/O 操作完成的时间比例。如果系统态时间比例高,并且 %wa 的值也较高,可能意味着系统正在进行大量的 I/O 操作,导致内核态时间增加。

    %st (或 %steal):
    这个参数只在虚拟化环境中出现,表示被管理程序(如虚拟机监控器)“偷走”的时间,用于为其他虚拟机提供服务。在非虚拟化环境中,这个值通常为 0。

    CPU 使用率:
    在 top 命令的顶部,会显示总的 CPU 使用率,包括用户态、系统态、空闲等。如果系统态时间比例高,总的 CPU 使用率也会相应较高。

    进程列表:
    在 top 命令的进程列表中,可以看到每个进程的 CPU 使用情况,包括用户态和系统态时间。如果某个进程的系统态时间比例较高,可能需要进一步分析该进程的行为。

    要分析具体的原因,而不是直接找代码问题。

    原因有很多很多情况:比较常见的—— 磁盘获取资源

    分析定位代码问题:

    获取线程栈定位代码 arthas

    下载: 百度搜索 arthas软件下载,上传到项目所在的机器

    wget https://arthas.aliyun.com/arthas-boot.jar;
    

    启动arthas: 首先,要确认机器上有 java进程 java -jar arthas-boot.jar

    java -jar arthas-boot.jar
    

    找到 导致项目机器cpu的使用率最高的 java进程的id, 输入这个进程在arthas中对应编号, 回车自动去连接到你选择的java进程
    我的这里先死是1
    在这里插入图片描述
    使用arthas:

    获取帮助: help

    查看线程栈: thread

    thread -n 5 显示出cpu使用率最高的5个线程栈信息
    展示信息如下:
    在这里插入图片描述
    根据展示的信息和项目信息寻找相关的日志

    在这里插入图片描述
    在这里插入图片描述

    根据日志我们可以定位到java程序中的67行和73行的代码需要优化。

    内存问题定位

    OOM

    OOM,全称为Out Of Memory,指的是程序在运行过程中因为没有足够的内存资源而导致的错误或问题。在性能测试中,OOM问题通常表明被测试的系统或应用在内存管理方面存在问题,可能是因为内存泄露、内存分配不当或者内存需求超过了系统可用的最大内存。

    主要导致OOM问题的因素:
    内存泄露:应用在运行过程中,未能及时释放不再使用的内存空间,导致这部分内存持续被占用,最终可用内存耗尽。

    过度内存分配:应用分配了过多的内存而没有足够的空间来满足这些请求,尤其是在32位系统上,应用程序可用的地址空间有限。

    资源竞争:多个进程或线程竞争有限的内存资源,导致某些进程无法获取足够的内存。

    缓存使用不当:缓存设置不当(如缓存对象太大或缓存时间太长)也可能导致可用内存迅速耗尽。

    不合理的数据结构选择:使用了过于复杂或大小不当的数据结构,导致内存使用效率低下。

    主要体现在哪些性能参数中:
    内存使用量:应用程序的内存使用量持续增加,尤其是在长时间运行时,是检测内存泄露的一个重要指标。

    GC(垃圾回收)频率和耗时:在一些使用自动内存管理的语言中(如Java、C#),频繁的垃圾回收操作可能表明存在内存泄露问题,尤其是当GC操作占用的CPU时间显著增加时。

    页面交换(Swapping):当系统的物理内存不足以满足需求时,操作系统会使用磁盘空间作为虚拟内存。频繁的页面交换活动(Swapping)可能表明内存资源紧张。

    响应时间和吞吐量变化:因内存压力导致的频繁垃圾回收或页面交换,会影响应用的响应时间和吞吐量,这些性能下降也可能是OOM问题
    的间接指标。

    OOM问题定位

    环境搭建:
    JvmPertest

    要求: jdk1.8、tomcat任意版本、操作系统windows、linux、mac

    • 项目部署: 把JvmPertest.war包,拷贝到 tomcat的webapps文件夹,启动tomat就可以

    • 启动Tomcat:

      • 切换到Tomcat的bin目录 ,使用startup.sh脚本来启动Tomcat: ./startup.sh
    • 检查Tomcat是否运行:

      • 你可以通过访问默认的Tomcat页面来检查它是否正在运行。在浏览器中输入 http://localhost:8080(或者你服务器的IP地址,如果你不是在本地机器上操作的话),你应该能看到Tomcat的默认页面。8080是Tomcat默认的HTTP端口,如果你更改了默认端口,需要相应地调整URL。
      • 在这里插入图片描述

    接口: http://机器ip:8080/JvmPertest/pertest1 -----机器ip,这个机器的防火墙

    对上面得劲接口进行性能测试,测试了一段时间 ,就看响应信息种出现了:java.lang.OutOfMemoryError:Java heap space。 错误,这个错误,OOM中的 堆溢出
    在这里插入图片描述
    OOM信息获取:
    oom问题是一个内存问题,不一定在日志中,能看到OOM的错误。接口返回信息中,也不一定有OOM错误信息。看机器内存条,内存条也是有剩余空间,不会把机器的所有内存都用完。

    如果项目日志中,有oom的错误,或者响应体有oom错误信息,或者机器内存都用完了,导致机器异常,这肯定是明显的OOM问题。

    如果没有,只能同通过监控手段来获取。

    • 如果是容器化部署项目: 如 docker docker stats 容器名称或id 就能看到容器的内存使用情况。 如果看内存使用率 接近100% 肯定是 OOM
    • 如果是直接用 tomcat部署的。搭建tomcat的jvm监控平台中看。

    OOM问题定位实战
    定位OOM问题

    arthas

    把tomat的bin文件夹下 catalina.sh文件 增加了 JAVA_OPTS=“-Xms256m -Xmx256m -Xmn128m” 设置tomcat的堆栈信息。 这样OOM内存溢出会更快,获取的 OOM的大小会更小。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    我们的进程时第4个
    在这里插入图片描述
    在arthas中 执行 heapdump 获取到了 堆栈信息。
    堆栈信息是一个二进制文件,后缀 .hprof 也可以是 .bin

    获取OOM堆信息定位代码

    下载hprof的二进制文件,用 MAT工具打开,怎么去看
    如果看不懂。 把hprof文件,给开发人员。

    tomcat性能调优

    tomcat配置文件:

    catalina.bat \ catalina.sh

    conf/server.xml

    tomcat的对外http协议的端口是 8080

    server.xml文件中,配置线程池

    tomcat性能调优 参考这里

    1、调整JVM参数:

    • 设置合适的堆内存大小(Heap Size),例如通过-Xms和-Xmx参数设置初始堆大小和最大堆大小。

      • 修改 bin文件夹中 catalina.sh文件, 调整里面 JAVA_OPTS=“-Xms值 -Xmx值 -Xmn值”
        • 设置一个值,然后性能测试,再调整,再性能测试,多次调整+测试,找到 性能最优解。
    • 优化垃圾回收器(Garbage Collector),例如使用-XX:+UseG1GC启用G1垃圾回收器。

    • 调整其他JVM参数,如-XX:MaxPermSize(对于Java 8之前的版本),-XX:MetaspaceSize(Java 8及以后版本)等。

    2、调整Tomcat配置:

    • 增加线程池大小,通过修改server.xml中的Executor和Connector配置。
      • minSpareThreads: tomcat初始化默认时默认创建的线程数,也是以后线程增加时一次增加的 最小数量
      • maxSpareThreads:这个参数标识,一旦创建的线程数量超过这个值,Tomcat 就会关闭不活 动的线程
        • 线程池最大可以保持的连接数量: maxThreads 乘以 acceptCount
    • 调整连接器(Connector)的参数,如maxThreads、acceptCount、connectionTimeout等。
      • acceptCount 最大可接受的排队数量
      • maxThreads 最大并发连接数
        • 如果是微服务,maxThreads这个值,一般都很小,常见的 就是 几个或者小几十
      • connectionTimeout 连接超时时间,单位毫秒
    • 启用压缩(Compression),通过设置compression和compressableMimeType属性。
    • 启用NIO或APR连接器,以提高I/O性能。
    • 连接池connector

    如果性能测试中,要求的并发用户数,达不到。可能原因: 应用支持的连接池不够。

    解决办法:

    1、修改tomcat的连接池的配置参数 maxThreads值, 适当的扩大。

    2、或者扩大应用副本数量。

    但是数量增大,必然会用更多的资源。

    tomcat性能调优实战:
    在Tomcat性能调优中,调整JVM参数和Tomcat配置是两个关键步骤。以下是如何设置合适的堆内存大小和调整Tomcat配置的详细操作步骤:

    设置合适的堆内存大小

    步骤 1: 评估内存需求
    • 使用监控工具(如JVisualVM、VisualVM、JMX等)来观察应用程序在运行时的内存使用情况。
    • 分析应用程序的内存使用模式,确定高峰期的内存需求。
    步骤 2: 设置JVM参数
    • 打开Tomcat的启动脚本(catalina.shcatalina.bat)。
    • JAVA_OPTSCATALINA_OPTS变量中添加以下参数:

    JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -Xloggc:gc.log "

    - `-Xms512m`:设置初始堆内存为512MB。
    - `-Xmx1024m`:设置最大堆内存为1024MB。
    - `-XX:+UseG1GC`:启用G1垃圾回收器。
    - `-XX:MaxGCPauseMillis=200`:设置垃圾回收的最大暂停时间为200毫秒。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9caafe82e1634089bb9b473b1c85fa69.png)
    #### 步骤 3: 重启Tomcat
    - 保存更改并重启Tomcat服务器以应用新的JVM参数。
    
    #### 步骤 4: 监控和调整
    - 继续监控应用程序的内存使用情况。
    - 根据监控结果调整`-Xms`和`-Xmx`的值,并重新测试。
    
    ### 调整Tomcat配置
    
    步骤 1: 编辑`server.xml`
    - 打开Tomcat的配置文件`server.xml`。
    
    步骤 2: 调整连接器(Connector)配置
    - 找到``元素,并根据需要调整以下属性:
    - `maxThreads`:设置最大线程数,例如`maxThreads="200"`。
    - `acceptCount`:设置当所有可能的请求处理线程都在使用时,传入连接请求的最大队列长度,例如`acceptCount="100"`。
    - `connectionTimeout`:设置连接超时时间,例如`connectionTimeout="20000"`(20秒)。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/df1f8accba624f749ed7f55485ee773a.png)
    
    步骤 3: 启用NIO或APR连接器
    - 如果使用的是阻塞I/O(BIO)连接器,考虑切换到NIO或APR连接器以提高性能。
    - 对于NIO连接器,设置`protocol="org.apache.coyote.http11.Http11NioProtocol"`。
    - 对于APR连接器,设置`protocol="org.apache.coyote.http11.Http11AprProtocol"`。
    
    步骤 4: 启用压缩
    - 在``元素中添加以下属性以启用压缩:
    ```xml
    compression="on"
    compressionMinSize="2048"
    noCompressionUserAgents="gozilla, traviata"
    compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
    

    步骤 5: 调整线程池(Executor)配置

    • 如果需要,配置线程池以共享线程资源:

      <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
          maxThreads="200" minSpareThreads="20"/>
      
    • 元素中引用这个线程池:

      executor="tomcatThreadPool"
      

    步骤 6: 重启Tomcat

    • 保存server.xml的更改并重启Tomcat服务器以应用新的配置。

    步骤 7: 监控和调整

    • 使用监控工具监控Tomcat的性能。
    • 根据监控结果调整配置参数,并重新测试。

    GC

    输出gc日志

    jvm的启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -Xloggc:gc.log

    启动后输出:GC概要信息、详细信息、gc时间、gc造成的应用暂停时间

    -Xloggc:文件名称 ----- 输出gc的信息到一个文件中, 文件只写文件名,就是到 tomcat的bin文件夹下

    在这里插入图片描述

    下载gc日志

    https://gceasy.io/

    tomcat监控

    grafana + prometheus + jvm_exporter

    grafana + prometheus 安装搭建详看这里

  • 相关阅读:
    图像分割算法
    【最全】linux服务器上安装Mysql
    Android简易音乐重构MVVM Java版 -搭建项目(八)
    操作系统——死锁
    Webpack 打包commonjs 和esmodule 模块的产物对比
    Opencv——图像添加椒盐噪声、高斯滤波去除噪声原理及手写Python代码实现
    python实现生存分析(Survival Analysis)
    MVC架构
    微型操作系统内核源码详解系列五(1):arm cortex m3架构
    MPP(无主备)环境搭建
  • 原文地址:https://blog.csdn.net/qq_35283902/article/details/139842218