结合glowroot和jmeter的性能优化
1. glowroot的使用
1.1 资源
1.2 使用
下载 , 在启动java程序时,加上参数 -javaagent:path/to/glowroot.jar 访问 http://localhost:4000就能看到分析界面了。
2. 场景
场景:首页接口,涉及的信息有用户信息、可兑换奖品信息、任务列表信息,在高并发的情况下,就会出现性能问题。
{ "errCode": "e0000", "errMessage": "ok", "body": { "signUser": { 用户信息 }, "signDailyLogs": [ 五天的签到信息 ], "signTasks": [ 任务列表信息 ], "signChangeAwards": [ { "changeAwardId": 4, "name": "爱奇艺会员", "awardType": "PHYSICAL", "modelId": null, "activityId": null, "imgUrl": "https://-425c-a47f-6acf10b4ce95_w200_h161.png", "count": 500, "remainCount": 485, "point": 1, "status": "OPEN", "position": 1, "validTime": "2018-12-30", "del": 0, "hadChangeWeek": false } ] } }
2.1 优化之前
1. 调用图分析
[^通过jmeter 200 并发的场景下,glowroot工具反馈出的调用图]:
最左边是一开始的压测图,可以看到jdbc获取连接的时间占用了很大的比例,很明显的连接不够的原因,查看配置文件发现连接只有 5 个,redis连接也只有 10个,配置上之后重新压测结果就是中间的图样,这时瓶颈在jdbc和代码处理了。
2. sql调用分析
优化1 : 从图表可看出,兑换奖品表有八千多次查询量,原因①是目前测试环境需要关闭配置隔天生效的设置,每次查询直接查DB,原因②首页的奖品库存需要实时展示,每个用户都会去查询,导致sql调用量增高,可以优化成:从缓存中获取实时库存,定时任务每隔一秒去刷新最新的 数据到缓存中即可,在 1000QPS的场景下,优势就明显多了,原本每秒需要1000次sql查询就缩短成每秒 1次sql查询了。 优化2:有些表的查询语句,都是同个用户id下进行,不过在不同层调用,这时可以统一优化,上层查询传递到下一层,实现减少调用量的目的。
2.2 第一次优化
1. 调用图分析
优化效果比较明显,目前只是将兑换奖品缓存规则设置回来还有就是库存实时使用定时任务的方式,db的连接显然减少了一些,不过这时能看到redis的调用时间占比居然很明显,多时达到了几十毫秒,原因可能是项目设置redis连接数不足,或者是该接口对redis操作很频繁。
2. sql调用分析
可以看到原先兑换奖品现在的查询数量已经降低了很多了,从业务方面也能接受一秒更新一次显示的库存。