01、常见概念
吞吐量(TPS, QPS)
简单来说就是每秒钟完成的事务数大概查询数。通常吞吐量大表明系统单位时间能处理处罚的哀求数越多,所以通常希望TPS越高越好
响应时间
即从哀求发出去到收到系统返回的时间。响应时间一般不取平均值,而是要去掉不稳定的值之后再取均值,比如常用的90%响应时间,指的就是去掉了10%不稳定的响应时间之后,剩下90%的稳定的响应时间的均值。从聚类的观点看,实在就是去掉离群点。
错误率
即错误哀求数与总哀求数之比。随着压力增长,有大概出现处理处罚哀求处理处罚不过来的情况,这时错误数会不断增长。
三者有极大的关联,任何孤立的数据都不能阐明问题。典型的关系是,吞吐量增长时,响应耽误有大概增长,错误率也有大概增长。因此,单拿出一个10w的TPS并不能阐明问题。
性能调优的思路
一般情况,调优必要有个条件条件,即无论是用线上的真实流水还是线下的压力测试让问题扩大化,显着化。
根据这些比较显着的征象去初判问题,收集证据去验证初判结果建立,然后分析征象产生的原因,并实验解决问题。
02、性能测试
对于新上的系统大概是有过较大代码改动的系统来说,做一次摸底测试还是很有必要的。一般来说,期望摸底的测试是一次对单机的压力测试。压力测试可以帮你大概搞清楚系统的极限TPS是多少,在压力上来时有没有暴露一些错误大概问题,系统大抵的资源占用情况是什么,系统大概的性能瓶颈在哪。
如下是一次摸底测试的设置和结果。
这是用12000并发用户对10台呆板压测的结果,可以看出,TPS到7w多,平均响应时间为82ms,错误率在2.5%。
从图中还可以得到哪些信息?起首,TPS在后期迅速着落,实际上已经支撑不了如此大的并发量,即进入崩溃区,这里有几个大概:
- 一是系统根本遭受不了如此大的并发量
- 二是系统中间有问题导致TPS下跌。
其次,随着时间增长,错误率显著增长,阐明系统已经处理处罚不了如此多的哀求。联合前面两点以及相对安稳的平均响应时间,大抵可以推断系统没法遭受如此大的并发。另外,由于是10台呆板,单台的TPS大概在7000多,以后的调优可以以此为依据。
对于应用的特点,也要在这时候分析出来,即应用大概占用的资源。比如是CPU密集型应用还是IO密集型应用(还可以细分为是磁盘密集还是网络 )
03、定义性能优化的目标
经常听到人说,做个性能优化,吞吐量越高越好;大概做个性能测试,目标TPS是50000。可实际拿到这个信息,可以大概做性能测试吗?这个目标富足清晰吗?
事实上,在我看来,未定义清晰的目标去做性能测试都是耍流氓。
性能优化的目标一般是吞吐量达到多少,90%响应时间小于多少,错误率小于多少。同时还必要关注其他的性能指标,cpu使用情况,内存使用情况,磁盘使用情况,带宽使用情况等。对于摸底测试已经发现问题的,可以针对该问题专门优化,比如负载较高,cpu消耗过大,则目标大概是TPS,响应时间以及错误率不变的情况下降低CPU负载。大概内存增长过快,gc较为频繁,则目标大概是找出大概的内存泄露,大概进行干系的jvm内存调优。总之,目标可以比较灵活调整,但一定要明白。
04、分析
分析的过程较为灵活,基本上是一千个系统有一千种表现。这里很难一一阐明。仅谈谈一些常见的方法,工具以及思路。
01、针对CPU
针对cpu的监控,实在linux已经提供了两个比较好用的工具,一个是top,一个是vmstat。关于这两个命令就不细说了,关于cpu主要关注4个值:us(user), sy(system), wa(wait), id(idle)。理论上他们加起来应该等于100%。而前三个每一个值过高都有大概表示存在某些问题。
us过高:
- 代码问题
比如一个耗时的循环不加sleep,大概在一些cpu密集盘算(如xml解析,加解密,加解压,数据盘算)时没处理处罚好
- gc频繁
一个比较容易遗漏的问题就是gc频繁时us容易过高,由于垃圾接纳属于大量盘算的过程。gc频繁带来的cpu过高常伴有内存的大量颠簸,通过内存来判断并解决该问题更好。
小本领:如何定位us过高的线程并查看它的状态。
a. top命令找到消耗us过高的历程pid
b. top -Hp pid找到对应的线程tid
c. printf %x tid转为16进制tid16
d. jstack pid | grep -C 20 tid16 即可查到该线程堆栈
sy过高:
- 上下文切换次数过多。通常是系统内线程数量较多,而且线程经常在切换,由于系统抢占相对切换时间和次数比较公道,所以sy过高通常都是自动让出cpu的情况,比如sleep大概lock wait, io wait。
wa过高:
- 等待io的cpu占比较多。
留意与上面情况的区别,io wait引起的sy过高指的是io不绝的wait然后唤醒,由于数量较大,导致上下文切换较多,夸大的是动态的过程;而io wait引起的wa过高指的是io wait的线程占比较多,cpu切换到这个线程是io wait,到那个线程也是io wait,于是总cpu就是wait占比较高。
id过高:
- 许多人认为id高是好的,其着实性能测试中id高阐明资源未完全使用,大概压测不到位,并不是好事。
02、针对内存
关于java应用的内存,通常只必要关注jvm内存,但有些特殊情况也必要关注物理内存。关于jvm内存,常见的工具有jstat 、jmap、pidstat、vmstat, top
jvm内存:
通常gc发买卖味着总归是有一块区域空间不敷而触发gc。而许多导致异常gc的情况通常是持有了不必要的引用而没有即时的释放,比如像cache这样的地方就容易处理处罚不好导致内存泄露引发异常gc。
有大概是程序的行为是正常的,但是由于没有设置对合适的gc参数导致异常gc,这种情况通常必要调优gc参数大概堆代大小参数。
Full gc 发生的情况:
minor gc提升到旧生代的平均大小大于旧生代剩余大小
CMS gc中promotion fail或concurrent mode fail
OOM:
OOM经常伴随着异常gc,之所以单独拿出来讲,是由于它的危害更大一些,异常gc顶多是收集速度过快大概接纳不了内存,但是起码有个缓冲时间,但是出了OOM问题就大了。
- heap区,对象创建过多或持有太多无效引用(泄露)大概堆内存分配不敷。使用jmap找到内存中对象的分布,使用ps找到相应历程及初始内存设置。
- stack区, 不正确的递归调用。
- perm区,初始加载包过多,分配内存不敷。
- 堆外内存区,分配ByteBuffer未释放导致。
03、针对IO
针对网络IO比较有用的工具有sar、netstat是一个非常牛逼的命令,可以助于排查许多问题, 针对文件io的工具有pidstat、iostat
1、文件IO:
从技能上来说,对于大文件IO可以采取的步伐是异步批处理处罚,采用异步方式用于削峰并累计buffer,采用批处理处罚可以大概让磁盘寻道连续从而更加快速。
2、网络IO:网络IO的问题较为复杂,仅举几个常见的
根据TCP协议,自动发起关闭连接的那一方,关闭了自己这端的连接后再收到被动发起关闭的那一方的关闭哀求后,会将状态变为TIME_WAIT,并等待2MSL, 目的是等待自己的回执发送到对方。如果在服务器上发现大量TIME_WAIT,阐明服务器自动断开了连接,什么情况下服务器会自动断开连接,很大概是客户端忘了断开连接,所以一个典型的案例就是jdbc连接忘记关闭,则数据库服务器大概会出现大量的TIME_WAIT状态。
CLOSE_WAIT状态,在收到自动关闭连接的一方发出关闭连接之后,被动关闭的一方进入CLOSE_WAIT状态,如果这时候被hang住了没进行后续关闭,则会出现大量CLOSE_WAIT。啥情况会被hang住呢,举几个例子,比如刚刚的忘记关闭数据库连接,在应用服务器这端,大量的欣赏器哀求进来,由于没有连接池连接被hang住,这时候欣赏器等待一定时间超时发送关闭连接哀求,而应用服务器这边由于servlet线程被hang住了,天然没有办法走第二个关闭回去。因此在应用服务器出现大量CLOSE_WAIT。
另一个例子是httpClient的坑,在调用response.getEntity(); 前都不会做inputStream.close(),如果在调用response.getEntity()前就返回了,就狗带了。
学习安排上!
软件测试学习资源分享
末了感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,固然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
下方这份完整的软件测试视频学习教程已经上传CSDN官方认证的二维码,朋友们如果必要可以自行免费领取 【保证100%免费】
这些资料,对于想进阶【自动化测试】的朋友来说应该是最全面最完整的备战堆栈,这个堆栈也伴随我走过了最艰难的路程,希望也能帮助到你!凡事要赶早,特殊是技能行业,一定要提升技能功底。希望对各人有所帮助……底子知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级连续集成、测试架构开发测试框架、性能测试、安全测试等配套学习资源免费分享
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |