记一次接口压力测试与性能调优
〇、经验总结
1.如果总的CPU占用率偏高,且基本都被业务线程占用时,CPU占用率过高的原因跟JVM参数大小没有直接关系,而跟具体的业务逻辑有关。
2.当设置JVM堆内存偏小时,GC频繁会导致业务线程停顿增多,TPS下降,最后CPU占用率也低了;
3.当设置JVM堆内存偏大时,GC次数下降,TPS上升,CPU占用率立刻上升。
4.Dom4J 这个xml解析工具性能很强大,但在处理节点和层级都较多的xml文本时,整体解析效率依然会成为业务处理瓶颈。
一、背景说明
最近新项目上线,需要对项目中的一个HTTP接口进行压力测试,以保证接口性能稳定性。该接口涉及到的主要业务是接收HTTP请求,获取请求中的xml报文参数,并将xml报文解析后存入MySQL数据库。接口业务流程如下:
该业务接口部署的服务器配置和部署MySQL组件的服务器配置一致,都是4核8G,50G普通硬盘,并且处于同一个内网网段,我们预估的性能指标要达到200并发,500TPS。
在压力测试过程中,我们重点关注TPS、GC次数、CPU占用率和接口响应时间等指标。
二、测试过程
完成项目部署后,我们开始编辑jemeter测试脚本,设置压力测试的标准为200个并发线程,在10秒内全部启动,持续压测时间15分钟,接着开始启动jemeter脚本进行测试。
1、第一次压力测试
(1)JVM配置
垃圾收集策略包括:老年代启用CMS垃圾收集算法,新生代启用ParNew垃圾收集算法,新生代最大存活周期为15次minorGC,FullGC时使用CMS算法,并开启CMS中的并行标记。
JVM内存分配:最大/最小堆内存为512MB,Eden和Survivor比例为8:2,永久代初始化64MB,最大128MB。
JVM配置参数如下:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+ExplicitGCInvokesConcurrent
-XX:+CMSParallelRemarkEnabled -Xms512m -Xmx512m -XX:SurvivorRatio=8 -XX:PermSize=64m -XX:MaxPermSize=128m
(2)性能指标监控
top命令观察java线程的CPU占用率(us表示用户进程,sy表示系统进程):
jemeter工具输出的TPS和接口响应时间:
jstat -gcutil {pid} {period_time} 输出GC情况
我们根据上述指标监控的情况可以看出,目前CPU占用率很高,每个CPU上的业务线程都占用了90%以上的CPU时间,年轻代GC次数频繁,平均每秒钟有8次左右,但TPS目前只有400左右。
一开始看到这个情况,我们以为是JVM堆内存分配的不足,导致GC频繁,从而引起CPU的高占用率。所以我们调大了堆内存参数,并进行第二次压力测试。
2、第二次压力测试
(1)JVM配置
JVM内存分配:最大/最小堆内存为2048MB,Eden和Survivor比例为8:2,永久代初始化512MB,最大512MB。
JVM配置参数如下:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+ExplicitGCInvokesConcurrent
-XX:+CMSParallelRemarkEnabled -Xmx2048m -Xms2048m -Xmn1024m -XX:NewSize=640m -XX:MaxNewSize=640m
-XX:SurvivorRatio=8 -XX:PermSize=512m -XX:MaxPermSize=512m
(2)性能指标监控
top命令观察java线程的CPU占用率(us表示用户进程,sy表示系统进程):
jemeter工具输出的TPS和接口响应时间:
jstat -gcutil {pid} {period_time} 输出GC情况:
根据上述指标监控的情况可以看出,这次JVM参数调整后,随着堆内存扩大,年轻代GC次数降低了,平均每秒有2次左右,TPS提高到600左右。但是CPU占用率依然很高,且都为业务进程占用。
从这个性能结果来看,堆内存的增大,可以降低GC频率,提高TPS。但CPU占用率几乎没有变化,可能的原因预计有两个:
第一、业务逻辑中存在耗CPU的计算操作;
第二、业务代码存在锁,导致大量线程在等待锁。
根据这个猜测,我们决定打印出JVM线程快照,看下能否找到线程等待锁的相关信息。
jstack -l {pid} > /log_dir/stack_log.txt 命令输出线程快照信息到指定的目录文件。
在线程快照文件里查找状态为BLOCKED的线程记录,发现出现较多BLOCKED状态的线程是:
从线程快照来看,大量xml解析线程处于BLOCKED状态,xml解析的业务处于阻塞状态,降低了接口处理效率。
接着我们把接口代码中其他逻辑代码屏蔽,只留下xml解析代码,发现CPU占用率依然在90%以上,而一旦把xml解析代码屏蔽,留下其他业务代码,CPU占用率马上降低到了70%,TPS上升,GC次数下降并保持稳定。
从上面这些处理的结果来看,CPU占用率过高的原因跟JVM参数大小没有直接关系,而跟xml参数解析有关,因为xml参数报文包含十几个节点,层级也较多,解析后生成的都是比较复杂的大对象。
当设置JVM堆内存偏小时,GC频繁会导致业务线程停顿,TPS下降,最后CPU占用率也低了;
当设置JVM堆内存偏大时,GC次数下降,TPS上升,CPU占用率立刻升高到95%以上。
由于我们对xml参数解析使用的是dom4j的方法,所以没办法在xml解析上面进行优化,只能在JVM参数和并发数上进行处理。
最终为了平衡CPU占用率、TPS、GC三个方面的指标,考虑业务实际场景,我们设置JVM堆内存为1.5G,限制TPS为200。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Pod定义与ConfigMap
Pod的作用 在k8s中pod是最小的管理单位,在一个pod中通常会包含一个或多个容器。在每一个Pod中都有一个特殊的Pause容器和一个或多个业务容器,Pause来源于pause-amd64镜像,Pause容器在Pod中具有非常重要的作用: Pause容器作为Pod容器的根容器,其本地于业务容器无关,它的状态代表了整个pod的状态。 Pod里的多个业务容器共享Pause容器的IP,每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost相互通信。k8s支持底层网络集群内任意两个Pod之间进行通信。 Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据。volumes还用于Pod中的数据持久化,以防其中一个容器需要重新启动而丢失数据。 kubernetes 的对象定义一般都用YAML或JSON格式的文件,可以使用这个网址验证yaml语法:https://codebeautify.org/yaml-validator Pod的定义 Kubernetes中所有的资源对象都可以采用YAML或者JS...
-
下一篇
一次walle项目错误处理--巨坑
一次walle项目错误处理--巨坑 Walle的简介我就不多说了它主要是一个web部署系统工具,具有一键快速回滚的功能,它能清晰的记录 上线单申请、审核、部署和实时操作日志,能支持各种web代码发布和回滚,对于jenkins来说应用时比较简单一点。 对于walle,我现在的公司主要是使用walle实现代码发布,(搭建可参考 walle搭建)下面是我配置的一个项目,(有修改,理解意思就好)先给大家贴个图. 各配置的理解如下: · 代码的检测仓库目录:如 /data/code/api · 项目的用户权限管理 www · 生产环境的web目录,该目录的最后一个目录不需要创建,发布时自动软连生成 如:/data/www/www.api.com · Walle的发布临时目录,存放web的版本 如: /data/publish/www/api · 部署前准备任务:pre-deploy (前置检查) · 代码检出后处理任务post-deploy:如vendor和处理php命令 · 同步后更新软链前置任务pre-release · 发布完毕后收尾任务post-release:如重启、一些文件的操作 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL数据库在高并发下的优化方案
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境