压测
压力测试考察的是当前软硬件环境下系统所能承受的最大负荷并帮助找出系统的瓶颈所在,压测都是为了系统在线上的处理能力和稳定性维持在一定的范围内,做到心中有数。
使用压力测试,我们有希望找到很多种用其他测试方法更能发现的错误,比如内存泄露、并发与同步等。
有效的压力测试系统将应用以下关键条件:重复、并发、量级、随机变化。
系统的性能指标
- 响应时间(Response Time:RT):响应时间指的是用户冲客户端发起一个请求开始,到客户端接收到从服务端返回的响应结束,整个过程所耗费的时间。
- HPS(Hits Per Second):每秒点击次数,单位次/秒。
- TPS(Transaction Per Second):系统每秒处理的事务数,单位是笔/秒,这里的事务不是具体指数据库事务,而是一个业务功能的全流程,比如下单功能的全业务流程称为一个事务,而TPS表示每秒能下单的数量。
- QPS(Query Per Second):系统每秒处理的查询次数。一般用TPS来衡量整个业务流程,用QPS来衡量接口查询次数,用HPS来表示对服务器的单击请求。这三者用吞吐量来解释。
- 最大响应时间:指的是用户发出请求开始,到收到服务器响应所耗费的最大时间。
- 最小响应时间:指的是用户发出请求开始,到收到服务器响应所耗费的最小时间。
- 90%响应时间:是指对用户的请求响应时间进行排序,第90%的请求的响应时间,比如100个请求的响应时间进行排序,那么第90个请求的响应时间就是90%响应时间。
- 从外部看,系统性能主要看三个指标:
)吞吐量:TPS、QPS。
)响应时间。
)错误率:一批请求中,响应结果出错的请求所占的比例。
性能优化实战
影响性能的问题考虑:
数据库、应用程序、中间件、网络、操作系统、业务代码等。
首先考虑是CPU密集型应用还是IO密集型应用,CPU密集型可能要加CPU核心,IO密集型可以换固态硬盘,或者使用缓存工具,比如Nginx。
该性能优化使用的是尚硅谷谷粒商城2020的首页接口来进行压测并优化。因为java程序。nginx啥的全部都是在同一台机器上,所以结果不是很标准,主要提供一个思路。
目前调用链路是这样的:
客户端->nginx->网关->首页
使用工具
- Apache Jmeter 压测工具
- JVisualvm 系统运行信息,比如线程、JVM的信息。
初始压测:
压测内容 | 压测线程数 | 吞吐量 | 90%响应时间 | 99%响应时间 |
---|---|---|---|---|
Nginx | 使用2000个线程压,每个线程压十次10次 | 3985 | 179 | 3022 |
Gateway | 使用2000个线程压,每个线程压十次10次 | 9925 | 1 | 3 |
首页一级菜单渲染 | 使用1500个线程压,每个线程压十次10次 | 209 | 8979 | 9519 |
三级分类获取 | 使用300个线程压,每个线程压十次10次 | 41 | 34901 | 37730 |
首页全量数据获取(一级菜单加各种静态文件js/css/图片等) | 使用50个线程压,每个线程压2次 | 24 | 2420 | 2569 |
全链路(包括静态资源) | 使用50个线程压,每个线程压2次 | 1.2 | 67961 | 75675 |
尝试优化系nginx,比如集群,这里没有多余的机器,就不集群了,那就尝试优化增加nginx的工作进程,原本是1个工作进程,因为虚拟机的cpu核心数是2,所以就增加一个工作进程。
压测内容 | 压测线程数 | 吞吐量 | 90%响应时间 | 99%响应时间 |
---|---|---|---|---|
Nginx(增加一个工作进程后) | 使用2000个线程压,每个线程压十次10次 | 5011 | 59 | 1118 |
得到了一些优化,吞吐量上去了,90%和99%的响应时间也变小了,如果cpu核心数更多,可以创建更多的工作进程,或者能够进行集群,那么优化效果更佳。
优化一级菜单渲染:
优化点:开启thymeleaf的缓存功能。把日志等级调到warn。数据库对parent_cid建立索引,JVM的堆内存调大。
因为当初为了能启动多个服务,把每个服务的JVM堆内存设置到了100m。导致频繁的触发yonggc和fullgc。
可以看到触发了759次fullgc,耗费了51.186秒。80次younggc,耗费了250毫秒,现在把内存调大,避免频繁的fullgc。
设置堆大小为1024m,新生代的大小为512m,因为这种业务大多数的对象都是短命的,请求结束后就死了。所以把新生代的大小稍微调大点。
参数:-Xms1024m -Xmx1024m -Xmn512m
压测内容 | 压测线程数 | 吞吐量 | 90%响应时间 | 99%响应时间 |
---|---|---|---|---|
首页一级菜单渲染 | 使用1500个线程压,每个线程压十次10次 | 1741 | 889 | 1055 |
相比原来的209吞吐量,增大了近9倍的吞吐量。并且该增长的瓶颈就在JVM的内存上,开启缓存、加表索引、关日志后的吞吐量达400,加上JVM内存后,大1741。
可见仅仅发生了两次fullgc,耗费51毫秒。
三级分类获取渲染
上面的开启thymeleaf的缓存功能。把日志等级调到warn。数据库对parent_cid建立索引,JVM的堆内存调大。在这里同样适用,并且我的业务代码问题不大,一开始就没有跟尚硅谷的老师那样循环访问数据库。所以我的业务代码无需更改。
因为查询三级分类,查询的数据量比较大,所以加索引的功效会明显于上面的一级分类。
吞吐量从41增长到297。并且只发送2次fullgc。
首页全量数据获取(一级菜单加各种静态文件js/css/图片等)
这里的优化手段是把静态资源文件放到nginx上转发,程序的tomcat服务器只处理动态请求。实现动静分离,因为tomcat会分出线程来对静态资源文件的处理。所以要实现动静分离。
把静态资源文件放上nginx后,直接访问商城访问不到静态文件,所以这里测试的是全链路,包括下载静态文件的吞吐量。
全链路不下载文件,的吞吐量达99.
其他优化思路
数据上缓存,比如redis,性能会得到巨大的提升。。集群。