全局图预览
通过对直播观看页进行高并发压测,在 APM(Pinpoint)监控中发现一个有趣的地方:
上图中两个红框中的数据(接近 10s),相隔大概 30 分钟就发生,16:20 左右,系统撑不住服务出现异常不可用,怀着好奇的心态,追查方法调用的栈,如下图所示:
该方法耗时多久呢?首先搞清楚 Call Tree 里面的一些概念:
可见这个 sql 查询方法耗时 14 秒多,为什么呢?APM 里面已经显示了 sql 语句,在 mysql 中执行查询发现执行时间很快,那么问题出在哪里呢?只能继续深挖!
通过对比同样的 url,请求响应毫秒级的情况下,发现数据如下图所示:
从 redis 获取到数据后,并没有再执行 sql 查询了,通过这个分析,我们决定追踪代码还原真相(不懂代码的测试不是好开发):
可以看到缓存失效之后,直接查询数据库了:一个缓存并发引起性能瓶颈的应用场景
从数据分析来看,sql 优化的用处不大,并不是返回了大量数据缺少索引,此次可以跳过。
性能瓶颈在缓存失效后,大量并发导致 mysql 访问量剧增,而当前采取的缓存策略是:先取 mysql 数据,再放入 redis 进行缓存。
出现场景:当网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询 DB,同时设置缓存的情况,如果并发确实很大,这也可能造成 DB 压力过大,还有缓存频繁更新的问题。
处理方法:对缓存查询加锁,如果 KEY 不存在,就加锁,然后查 DB 入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入 DB 查询。
1、善用监控工具,例如 APM,进行链路监控、服务器性能、方法调用顺序观察
2、追踪方法栈和相关日志
3、深入排查代码挖本质