文章目录
概述
1.性能指标
从外部看,性能测试主要关注如下三个指标【量越大越好,时间越少越好】
吞吐量:每秒钟系统能够处理的请求数、任务数。
响应时间:服务处理一个请求或一个任务的耗时。
错误率:一批请求中结果出错的请求所占比例。
响应时间rt(重要)
响应时间(response time:rt)
响应时间指用户从客户端发起一个请求开始,到客户端接收到从服务器端返回的响
应结束,整个过程所耗费的时间。
错误率(重要)
错误率 一批请求中结果出错的请求所占比例。
hps
hps(hits per second):
每秒点击次数,单位是次/秒。
tps吞吐量(重要)
tps(transaction per second):
系统每秒处理交易数,单位是笔/秒。
qps(重要)
**qps(query per second):系统每秒处理查询次数,单位是次/秒。**
对于互联网业务中,如果某些业务有且仅有一个请求连接,那么tps=qps=hps,一
般情况下用 tps来衡量整个业务流程,用qps来衡量接口查询次数,用hps来表
示对服务器单击请求。
**无论tps、qps、hps,此指标是衡量系统处理能力非常重要的指标,越大越好,根据经**
**验,一般情况下:**
金融行业:1000tps~5000otps,不包括互联网化的活动
保险行业:100tps~10000otps,不包括互联网化的活动
制造行业:10tps~5000tps
互联网电子商务:1000otps~1000000tps
互联网中型网站:1000tps~50000tps
互联网小型网站:50otps~10000tps
最大响应时间
最大响应时间(maxresponse time):
指用户发出请求或者指令到系统做出反应(响应)
的最大时间。
最少响应时间
最少响应时间(mininum responsetime):
指用户发出请求或者指令到系统做出反应(响应)的最少时间。
90%响应时间
90%响应时间(90%response time)**是指所有用户的响应时间进行排序,第90%的响
应时间。
2.压测工具
apache ab
加特林
jmeter
文档网址:https://jmeter.apache.org/download_jmeter.cgi
zip安装包:
https://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-5.3.zip
jmeter
1.使用步骤
1.1.添加线程组
线程属性值含义:
线程数:200
ramp-up时间:1【1秒启动200个线程】
循环次数:100【每个线程发送100个请求,一共200*100 = 20000个请求】
1.2.添加取样器
取样器:
表示测试何种请求,这里使用http请求
1.右键线程组=》添加取样器=》http请求=》
2.指定url,端口,参数,请求类型
1.3.添加监听器
察看结果树
查看每次请求是否成功
汇总报告
聚合报告
2.jmeteraddress already in use 错误解决
windows帮助文档:
https://support.microsoft.com/zh-cn/help/196271/when-you-try-to-connect-from-tcp-ports-greater-than-5000-you-receive-t
windows本身提供的端口访问机制的问题。
windows提供给 tcp/ip链接的端口为1024-5000,并且要四分钟来循环回收他们。就导致
我们在短时间内跑大量的请求时将端口占满了。
1.cmd中,用regedit命令打开注册表
2.在hkey_local_machine\system\currentcontrolset\services\tcpip\parameters下
1.右击parameters,添加2个新的 dword,名字为maxuserport、tcptimedwaitdelay
2.然后双击maxuserport,输入数值数据为65534,基数选择十进制(如果是分布式运
行的话,控制机器和负载机器都需要这样操作哦)
3.然后双击tcptimedwaitdelay,输入数值数据为30,基数选择十进制(如果是分布式运
行的话,控制机器和负载机器都需要这样操作哦)
4.修改配置完毕之后记得重启机器才会生效
3.优化
3.1.影响性能考虑点
1.影响性能考虑点包括:【这里可以从访问顺序来作为链路进行性能调优】
数据库、应用程序、中间件( tomact、gateway、nginx、)、网络(带宽)和操作系统等方面
2.首先考虑自己的应用属于cpu密集型还是io密集型,根据jvisualvm查看应用健康情况
cpu:计算、排序、过滤、整合【集群】
io:网络、磁盘、数据库、redis【内存+缓存+固态+提高网卡的传输效率】
3.监控执行时中间件cpu、内存使用量
docker stats:查看cpu占用、内存使用量、
例如:minorgc每次都能干净释放eden,表示很健康
3.2.jvm内存模型
1.主要优化堆
避免发生fullgc
创建对象:
jconsole和jvisualvm
jdk小工具,通过命令行启动可以监控本地和远程应用【远程应用需要配置】
1.cmd输入【推荐使用这个】
jvisualvm
2.安装插件visual gc(用于监控垃圾回收)
如果不能安装插件(点击检查最新版本异常):
1)进入该链接:https://visualvm.github.io/pluginscenters.html
2)java -version 查看版本1.8.0_171
3)找到对应版本复制链接:https://visualvm.github.io/uc/8u131/updates.xml.gz
4)点开设置,编辑插件中心,粘贴url
5)安装插件visual gc
visual gc:
3.3.优化步骤(重点)
1.使用jmeter压测nginx、网关、直接访问服务、通过链路访问服务
2.测nginx时使用docker stats查看cpu占用+内存使用量,调整cpu性能
3.测网关时,打开jvisualvm查看内存、cpu使用量,调整cpu、内存
增加jvm内存:-xmx512m
4.记录下压测指标填在下表中
1)先优化各中间件
2)使用更好的协议
3)买更好的网卡+网线+带宽
5.压测说明:
1)首页渲染(全量数据获取) localhost:10000
选中高级,从html文件获取所有内含的资源、并行下载数量
6.指标:
1)中间件越多,性能损失越大,损失在网络交互
2)命中率不低于95%
3)锁等待次数越低、时间越短越好
4)业务:
db(mysql优化,加索引 parent_cid pms_category表)
在navicat中管理索引,右键添加
模板渲染速度(thymeleaf开启缓存) spring.thymeleaf.cache= true
静态资源(把静态资源放到nginx里面)
日志级别改成error(打印日志会耗时)
logging:
level:
com.atguigu.gulimall: error
5)堆内存优化 -xmx1024m -xms1024m -xmn512m【测试gulimall全量资源时,同时打开jvisualvm查看内存gc情况】
nginx动静分离:
静态资源也会由客户端发起请求,并且请求是gulimall.com/static/**,这个请求会重新经过nginx
1、所有项目的静态资源都应该放在nginx里面
2、规则:/static/***所有请求都由nginx直接返回
1)在nginx新建文件夹:/mydata/nginx/html/static,将product的static下的index文件夹拷过来
之前的静态资源请求:gulimall.com/index/img/section_second_list_right_img.png
2)修改项目内部静态资源的请求路径:ctrl+r
src="index/ =》 src="/static/index/
href=" =》 href="/static/
<script src=" => <script src="/static/
<img src=" => <img src="/static/
url('/ =>
3、修改nginx配置,gulimall.conf,监听gulimall.com:80/static,返回root
location /static {
root /usr/share/nginx/html;
}
三级分类数据获取【超级慢】
1)、优化业务逻辑:
1、一次性查询出来
小技巧:
将以下语句快速抽取为一个方法,选中右键:refacto=》extract=》method
basemapper.selectlist(new querywrapper<categoryentity>().eq("parent_cid", level1.getcatid()));
全量数据获取:
nginx动静分离
1.未动静分离,指的是静态资源全都存储在tomcat中,所有静态资源都要从tomcat获取,
会访问 nginx->gateway->tomcat获取静态资源,从而导致占用tomcat很多线程来处理静态资源
2.动静分离,表示将资源与web服务器分离,可存放在nginx中,静态资源直接从nginx中返回
/static/**所有请求都由nginx直接返回
步骤:
1)cd /mydata/nginx/html
mkdir static
2)将product项目内static文件夹下的index文件夹,拖到/mydata/nginx/html/static此目录下
3)修改index.html中静态资源的请求路径
src="index/ =》 src="/static/index/
href=" =》 href="/static/
<script src=" => <script src="/static/
<img src=" => <img src="/static/
url('/ =>
动静分离前下例请求会访问nginx=》gateway=》product=》static...
http://gulimall.com/index/img/img_09.png
分离后使用下例请求直接访问nginx中的静态资源
http://gulimall.com/static/index/img/img_09.png
4)修改gulimall.conf配置(监听gulimall.com/static请求,使用root作为根路径查找静态资源):
location /static/ {
root /usr/share/nginx/html;
}
解析:/static/index/img/img_09.png会找到挂载目录/usr/share/nginx/html
/usr/share/nginx/html/static/index/img/img_09.png
模拟线上崩溃
拿200个线程循环压测+静态资源获取+并行下载
测试首页 gulimall.com 80
崩溃:
1.堆内存溢出,线程池报错
2.gulimall-product下线无法请求503
加大内存,开启以上所有的优化步骤
内存即将溢出:
堆溢出,线程池报错:
实例下线:
优化三级分类
/**
* 查询三级分类并封装成map返回
*/
@override
public map<string, list<catalog2vo>> getcatalogjson() {
// 1.查询所有分类,按照parentcid分组
map<long, list<categoryentity>> categorymap = basemapper.selectlist(null).stream()
.collect(collectors.groupingby(key -> key.getparentcid()));
// 2.获取1级分类
list<categoryentity> level1categorys = categorymap.get(0l);
// 3.封装数据
map<string, list<catalog2vo>> map = level1categorys.stream().collect(collectors.tomap(key -> key.getcatid().tostring(), l1category -> {
// 3.查询2级分类,并封装成list<catalog2vo>
list<catalog2vo> catalog2vos = categorymap.get(l1category.getcatid())
.stream().map(l2category -> {
// 4.查询3级分类,并封装成list<catalog3vo>
list<catalog2vo.catalog3vo> catalog3vos = categorymap.get(l2category.getcatid())
.stream().map(l3category -> {
// 封装3级分类vo
catalog2vo.catalog3vo catalog3vo = new catalog2vo.catalog3vo(l2category.getcatid().tostring(), l3category.getcatid().tostring(), l3category.getname());
return catalog3vo;
}).collect(collectors.tolist());
// 封装2级分类vo返回
catalog2vo catalog2vo = new catalog2vo(l1category.getcatid().tostring(), catalog3vos, l2category.getcatid().tostring(), l2category.getname());
return catalog2vo;
}).collect(collectors.tolist());
return catalog2vos;
}));
return map;
}
3.x.压测指标
吞吐量括号内表示瓶颈,(db)表示瓶颈在db
压测内容 | 压测线程数 | 吞吐量/s | 90%响应时间 | 99%响应时间 |
---|---|---|---|---|
nginx | 50 | 8788 | 2 | 200 |
gateway localhost:88 | 50 | 32719 | 3 | 5 |
简单服务 localhost:10000/hello | 50 | 5624 | 20 | 73 |
首页渲染 localhost:10000/index.html | 50 | 850(db,thymeleaf) | 442 | 729 |
首页渲染(开缓存) | 50 | 214 | 380 | 710 |
首页渲染(thymeleaf开缓存+优化数据库+日志级别:error) | 50 | 480 | 159 | 253 |
三级分类数据获取 localhost:10000/index/catalog.json | 50 | 2(db) | 26311 | 27335 |
三级分类数据获取(加索引) | 50 | 5 | 9597 | 10176 |
三级分类数据获取(优化业务逻辑(一次性查询)+加索引+堆内存) | 50 | 65 | 1150 | 1849 |
三级分类数据获取(优化业务逻辑(一次性查询)+加索引+堆内存+redis缓存) | 50 | 390 | 155 | 296 |
三级分类数据获取(优化业务逻辑(一次性查询)+加索引+堆内存+redis缓存+分布式锁) | 50 | 313 | 212 | 355 |
首页渲染(全量数据获取) localhost:10000/index.html【废弃】 | 50 | 13(静态资源) | 4916 | 6954 |
首页渲染(全量数据获取+动静分离)gulimall.com | 50 | 8.2 | 8514 | 13435 |
首页渲染(全量数据获取+动静分离+堆优化)gulimall.com | 50 | 8 | 8311 | 13411 |
nginx+gateway | 50 | |||
gateway+简单服务 localhost:88/hello | 50 | 1180 | 80 | 142 |
全链路(nginx+gateway+简单服务) gulimall.com/hello | 50 | 532 | 126 | 226 |
发表评论