常见的互联网架构中,通常都能看到spring+mybatis+mysql+redis搭配的身影,在我所服务的公司亦是如此。通常来讲,应用内部的接口都是直接调用的,所谓的面向接口编程,应用间的调用直接调或者经过相似dubbo之类的服务框架来执行,数据格式每每采用json,即统一也方便各数据间作转换和取值,缓存通常使用redis或memcached,存储一些对象或json格式的字符串。对外提供的接口,通常都须要进行压力测试,以便估算其性能,并为后续的调优提供指导方向,如下接口即是在压测过程当中出现的各类“奇怪现象”,所谓奇怪,指的是从表象上看与咱们正常的逻辑思路不符,但其本质仍是咱们对压力下程序的表现出来的特征不熟悉,用惯用的知识结构试图去解释,这根本是行不通的。下文是我在一次全面压测过程后对数据进行的分析汇总,其中的现象是不少压测常见的,里面的分析过程及改进措施我认为有很大的参考意义。具体内容以下:(部分接口为了安全我省略了其名称,但不影响咱们的分析,另外形如1N3T之类的表示的是1台nginx,3台tomcat,具体的tps数值只是为了说明优化先后的比照,没有实际意义)html
1 接口名称: 获取列表
1.1 压测现象:单台tps700多,应用cpu高负载
1.1.1 问题分析:
旧框架,平均响应时间长,应用CPU高,程序内部有大量的bean到map到json之间的转换,修改数据库链接数后,tps没有提高。前端
1.1.2 改进措施:
重构系统,用mybatis替代以前的dao操做,减小bean-map-json之间的内部数据转换,减小程序内部的无用操做。java
1.1.3 改进效果:
tps改进后能到3000左右,有较大提高,但压测时应用cpu几乎跑满,还有改善空间。mysql
1.2 压测现象:数据库资源利用率高
1.2.1 问题分析:
单台应用,数据库资源cpu都能到50%,10台tomcat在1万并发下数据库cpu跑满,load值700多,但db的qps也不过11554,并不算多,所以怀疑是sql执行耗费了cpu,多是某条sql没有按索引查找或者索引失效。nginx
1.2.2 改进措施:
查看SQL文件发现以下sql:select count(1) from orders where order_status_id !=40 ,将其改成select order_id from orders 而后经过程序把order_status_id!=40的过滤掉。经过list.size()来获取。order_status_id即便加了索引,因为是!=比较,因此不会去按索引查找,致使cpu高redis
1.2.3 改进效果:
相同环境下(1台nginx,10台tomcat,1000并发),tps由3000变成3727,略有增加,可是db的cpu明显降低,变为30%,效果明显spring
1.3 压测现象:1N15T ,tps4552;10N15T,tps9608
1.3.1 问题分析:
后端都是15台tomcat,前端1台nginx时tps为4552,经过lvs挂10台nginx时为9608,增加不明显,其nginx和tomcat都压力不大,集群结果不合理,怀疑是nginx转发配置的问题;sql
1.3.2 改进措施:
未进一步改进:多是须要调整nginx的参数,以前发现过nginx不一样的配置对后端集群环境的tps影响很大数据库
1.3.3 改进效果:
2 接口名称: 信息查询接口
2.1 压测现象:单台tps2000多,应用cpu高,db的qps15000左右
2.1.1 问题分析:
旧框架,程序内部有不少Bo-map-json相互的转换编程
2.1.2 改进措施:
删除冗余代码、更换链接池包,使用mybatis
2.1.3 改进效果:
Tps由2000多增加为8000多,db的qps为9000左右,优化后压测应用的cpu占用高,几乎跑满。
2.2 压测现象:数据库无压力,应用增长多台后tps不变
2.2.1 问题分析:
1N1T和1N10T的tps同样,都为5000,增大并发时错误数增多,应用cpu耗费70%,db无压力,nginx单台经过ss –s 发现端口占满,即nginx到tomcat之间转发的链接端口time-wait状态6万多。Nginx存在瓶颈。
2.2.2 改进措施:
调优nginx参数,将短链接改成长链接
2.2.3 改进效果:
1N3T的tps能到17376,tomat的cpu压力84%,db的qps18000,cpu69%,应用的资源基本使用到量。
3 接口名称: 获取详情
3.1 压测现象:单台应用tps2600,10台tomcat才3700
3.1.1 问题分析:
增长应用服务器,tps增加不明显,且nginx、tomcat、db的负载都不高,说明服务器自己不是瓶颈,考虑是否是网络的问题,经过监控网卡包流量发现网络数据跑满,由于此接口会有大量数据的输出,所以瓶颈在网络上。另外,测试过程当中发现redis有报错,redis服务器是虚机,可能服务能力有限。
3.1.2 改进措施:
开启tomcat的gzip压缩。
3.1.3 改进效果:
同等并发下(1台nginx,10台tomcat,1000并发),tps由3727增加到10022,增加了近3倍,效果显著。
3.2 压测现象:1N10T集群下nginx参数调优对tps提高效果明显
3.2.1 问题分析:
通过tomcat的启用gzip后,1N10T下tps为10022,需进一步提高。
3.2.2 改进措施:
优化nginx:
l nginx日志关闭
l nginx进程数量worker,由24改成16
l nginx keepalive数量由256改成2048
3.2.3 改进效果:
Tps由10022提高为13270。
3.1 压测现象:1N5T和1N10T的tps相差不大
3.1.1 问题分析:
1N10T的tps为1万3千多,1N5T的tps为1万2千多,相差不大,应用的tomcat资源利用没满,cpu为65%,Db的QPS已经到2万多了,单台服务器db基本上到量了,所以再增长应用也没效果,只会致使响应的时间变长。
3.1.2 改进措施:
单台db已经没法改进了,要不提高服务器硬件,要不读写分离。
3.1.3 改进效果:
4 接口名称: 促销
4.1 压测现象:经过redis存取数据,tps才1000多,CPU 有压力
4.1.1 问题分析:
此接口经过redis取数据,tps不高才1000多,但cpu占用了80%,说明程序内部有大量序列化反序列化的操做,多是json序列化的问题。
4.1.2 改进措施:
将net.sf.json改为alibaba的fastjson。
4.1.3 改进效果:
同等并发条件下tps由1000多提高为5000多,提升了近5倍。
4.1 压测现象:参数多时tps降低明显
4.1.1 问题分析:
此接口根据参数从redis中获取数据,每一个参数与redis交互一次,当一组参数时tps5133,五组参数时tps1169,屡次交互影响了处理性能。
4.1.2 改进措施:
将从redis获取数据的get改成mget,减小交互次数。
4.1.3 改进效果:
五组参数时1N3T压测TPS9707,据此估算即便是单台tomcat,tps也能有三四千,性能比单次get的调用方式提高了3,4倍。
4.2 压测现象:1N3T tps1万多,在增大tomcat可能tps增加不会明显
4.2.1 问题分析:
此处说的是可能,由于nginx服务器的cpu虽然不高,但pps已经800多k,此时应该是nginx的服务器网络流量成为了瓶颈。(只是猜想)
4.2.2 改进措施:
能够增长多台nginx负载,前端加lvs
4.2.3 改进效果:
5 接口名称: 追踪接口
5.1 压测现象:1N10T的tps低于1N3T的tps
5.1.1 问题分析:
1N3T在2000并发下tps为9849,此时db的qps为90000,CPU80%,将tomcat增到10台,5000并发下,tps为7813,db的qps为19000,cpu75%,load 1,说明压力增大状况下db的压力反而下来了,注意到nginx服务器的网卡流量达到885M,说明是压力过大状况下,网络满了,发生丢包,致使db端压力反而下来了。
5.1.2 改进措施:
注意压测状况下部分接口因为数据量传输较大,会出现网络瓶颈。
5.1.3 改进效果:
6 接口名称: 回填接口
6.1 压测现象:tps不到500,db的qps3500
6.1.1 问题分析:
虽然缺乏应用的cpu及db的cpu利用率数据,较低的tps应该是应用的瓶颈,且须要关注是否是db在处理查询的时候缓慢。
6.1.2 改进措施:
1.链接池由dbcp改成hikar;
2.减小了日志打印输出
3.sql优化,将部分条件过滤改成在java代码中执行
6.1.3 改进效果:
Tps由不到500增加为1300多。
7 接口名称: 券查询
7.1 压测现象:集群结果与单台应用结果相比不合理
7.1.1 问题分析:
查看是否存在瓶颈资源,能够看到5台tomcat集群下,tps为9952,但db的qps为5-6万,cpu利用率为37%,说明对数据库进行了大量的主键或索引查询,通常单台db的qps也就4万左右,再增长应用的集群数量,对tps也不会有太大影响。
7.1.2 改进措施:
能够考虑分库
7.1.3 改进效果:
8 接口名称: 推荐
8.1 压测现象:nginx长短链接差别
8.1.1 问题分析:
18nginx,2tomcat时tps8100,此时应用服务器的端口数满, 通常来讲,Nginx短链接在高并发下容易致使端口占满的问题。
8.1.2 改进措施:
将nginx改成长链接
8.1.3 改进效果:
tps增加为10733,TPS稳定,起伏减小,可是CPU耗尽。说明cpu打满了,此时若是还要优化就的进行代码调优了。
9 接口名称: 查询2
9.1 压测现象:18N20T的tps才6842
9.1.1 问题分析:
18台nginx,20台tomcat,tps才6842,此时应用cpu利用率85%,说明cpu存在瓶颈,但检查此接口并未作大计算量的工做,有多是日志的级别问题,cpu在频繁的打日志。
9.1.2 改进措施:
将日志级别由debug级改成info级
9.1.3 改进效果:
同等环境tps由6842增加为23592.坑爹的生产环境debug日志级别。