目录:导读
- 前言
- 一、Python编程入门到精通
- 二、接口自动化项目实战
- 三、Web自动化项目实战
- 四、App自动化项目实战
- 五、一线大厂简历
- 六、测试开发DevOps体系
- 七、常用自动化测试工具
- 八、JMeter性能测试
- 九、总结(尾部小惊喜)
前言
1、性能测试-内存溢出问题定位和分析
堆内存溢出:
1)稳定性压测一段时间后,jmeter报错,日志报java.lang.OutOfMemoryError.Java heap space。
2)用jmap -histo pid命令dump堆内存使用情况,查看堆内存排名前20个对象,看是否有自己应用程序的方法,从最高的查起,如果有则检查该方法是什么原因造成堆内存溢出。
3)如果前20里没有自己的方法,则用jmap -dump来dump堆内存,在用MAT分析dump下来的堆内存,分析导出内存溢出的方法。
4)如果应用程序的方法没有问题,则需要修改JVM参数,修改xms,xmx,调整堆内存参数,一般是增加堆内存。
栈内存溢出:
1)稳定性压测一段时间后,jmeter报错,日志报Java.Lang.StackOverflowError。
2)修改jvm参数,将xss参数改大,增加栈内存。
3)栈溢出一定是做批量操作引起的,减少批处理数据量。
持久代溢出:
1)稳定性压测一定时间后,日志报Java.Lang.OutOfMemoryError.PermGen Space。
2)这种原因是由于类、方法描述、字段描述、常量池、访问修饰符等一些静态变量太多,将持久代占满导致持久代溢出。
3)修改jvm配置,将XX:MaxPermSize=256参数调大。尽量减少静态变量。
线程死锁:
1)容量测试压测一段时间后,LR报连接超时。
2)造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
3)jstack命令dump线程栈,搜索线程栈里有没有block,如果有的话就是线程死锁,找到死锁的线程,分析对应的代码。
数据库死锁:
1)容量测试压测一段时间后,LR报连接超时。
2)造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
3)数据库日志中搜索block,能搜到block的话就是存在数据库死锁,找到日志,查看对应的sql,优化造成死锁的sql。
2、常见单业务场景和混合业务场景性能bug
bug1:
我之前做压力测试压测一段时间后,频繁的报连接超时和socket close套接字关闭
原因:当时我们分析是因为Tomcat中间件线程池不够用,数据库连接池也不够,并且连接数也被占满了导致我们连接不上而报超时和套接字关闭等错误
性能bug2:
还有一次就是我在做压测的时候,我用50并发压测,TPS曲线正常应该是平缓的,但是TPS曲线剧烈下降和抖动,并且一直持续定位问题:当时我在服务器端用的jheap和dstat命令监控发现
是因为jvm进行垃圾回收的时候,老年代空间也满了引发了fullGC,然后导致我们线程暂停了进行垃圾回收,后面解决这个问题的话是我们开发同事把那个老年代的空间进行了增加,修改了JVM参数,并且增加了堆内存xms和xmx,后面fullGC频率就变低了很多。
性能bug3:
稳定性压测一段时间后,jmeter报错,日志报堆内存溢出OutOfMemoryError,后面我们开发同事把JVM的参数改了一下,增加堆内存把xms和xmx都调大了就没报错了
性能bug4:
压测一段时间后,jmeter报错,日志报栈内存溢出StackOverflowError。后面我们开发同事把JVM的参数改了一下,增加栈内存把xss参数改大了,后面就没报错了
性能bug5:
有次压一个查询接口的时候发现接口的平均响应时间非常的长,后面定位发现是因为在数据库用联合索引的时候,作为查询条件的那个字段没有放在查询条件的最左前缀,导致索引失效了,后面变成了全表扫描,后面我们给字段加了唯一索引,查询时间就提高了很多
性能bug6:
我有次压测的时候发现应用服务器的CPU达到90%,并且还是8核的CPU,当时就觉得有很大的问题,后来通过jprofiler工具对CPU进行了监控,发现有个谷歌开发的gson库在调用的时候对CPU的消耗非常的大
当时把这个问题反馈给到了开发,开发同事那边把这个谷歌的gson库换成了阿里巴巴的fastJSON后,发现性能好了不止一倍,CPU的占用只有20%、并且tps也提升上来了
性能bug7:
当时碰到过一个最难的性能bug,就是压测一段时间后,线程直接不动了,并且TPS直接为0了,但是呢服务器硬件的资源CPU和内存 IO等等又都是非常空闲的、通过JDK自带的jvisualvm工具我在查看线程的时候发现至少有2个线程一直处于红色的阻塞状态
后来在查看报错日志的时候发现有个CaseController类报错了、然后去看一下Java代码、发现代码里面一个锁synchronized里面又嵌套了另外一个锁,后面我们研发同事看了之后,改了一下代码把Thread.sleep()线程等待和锁里面加锁的代码给优化了,后续就没问题了
性能bug8:
有次我在做压测的时候,发现TPS就是上不去,然后呢通过用dstat -tcmnd --disk-util 命令去监控的时候发现CPU的使用率始终没有很大的波动、空闲95%左右、只占用了5%左右、当时就觉得应该不是fullGC和youngGC 内存泄露和内存溢出的问题。
为了进一步的排查和定位我后面通过通过jstack 进程号 >1.log命令去获取对应的日志、看一下是不是线程阻塞的问题,然后把捕捉的日志下载到本地用notepad++打开、发现Thread.stat:Blocked阻塞的地方多达70多个地方。
后面又通过反编译工具把log4j的jar包打开、找到了Category.class这个类、发现里面的第204行调了一个方法叫做callAppenders里面用了synchronized的锁,原因找到了是log4j里面为了保证线程的安全,里面加了很多的锁但是却牺牲了很多的性能
后面我们优化的时候就是首先进入项目中找到log4j.properties这个文件然后把log4j.rootLogger=info 中的info改为error、提升打日志的等级,然后重启项目,这个进行优化之后、重新压测发现TPS达到了7000/sec 、优化阻塞之后发现性能提升了3倍左右、CPU也占用了15%左右。
当然也可以用log4j2打日志,因为这个log4j2在原来的log4j的基础上做了重构做了性能的优化、做了异步处理比log4j和logback有了18倍的性能的提升
性能bug9:
在做压力测试的时候,吞吐量tps上不去,原本的TPS标准是要达到400/sec,但是实际压测只有50多的tps,后面发现是数据库的磁盘空间满了,导致查询速度和请求速度过慢,然后我让我们后端开发同事把数据库的磁盘清理一下就恢复正常了。
性能bug10:
我在压测(修改密码,新建用户,投保用户列表接口,保单管理接口,支付接口,保单查询接口,查看险种接口,投保接口)接口的时候【这里面接口自己选一个】,平均响应时间在10s左右,不符合性能指标3s,后来发现:原因是接口通过redis,每次请求redis都会初始化,后面我们在测试环境增加路由配置之后,这个问题就解决了
完整版!企业级性能测试实战,速通Jmeter性能测试到分布式集群压测教程
| 下面是我整理的2026年最全的软件测试工程师学习知识架构体系图 |
一、Python编程入门到精通
二、接口自动化项目实战
三、Web自动化项目实战
四、App自动化项目实战
五、一线大厂简历
六、测试开发DevOps体系
七、常用自动化测试工具
八、JMeter性能测试
九、总结(尾部小惊喜)
人生最动人的风景,往往藏在最难攀爬的高处。当你觉得力竭时,请记住:每一次坚持都在雕刻更强大的自己。别问路有多远,只管迈步向前;别怕山有多高,向上攀登就是答案!
你体内沉睡着改变世界的力量!每个清晨都是改写命运的新机会,每次挫折都是精心包装的礼物。当全世界都在说"不可能"时,正是你证明"可能"的最好时机!