网关504给我上压力,逐步排查引出三大接口逻辑优化~

973 阅读4分钟

背景

业务接口经常504,直接被拉群上压力,让排查排查怎么回事。

image-20240519132540345

排查 and 优化


优化1

先上阿里云arms看了下接口耗时情况,不看不知道,一看吓一跳,耗时尖刺多如牛毛。。。怪不得给我上压力 hhh

image-20240519132848236

然后挑一条耗时比较高的Trace查看,发现有条sql执行的贼慢,还是count(*)

image-20240519140205006

image-20240519133518474

拿着这条sql,代入一些参数,自己去生产环境跑了下,倒没有这么慢啊

因为用的是pg,可以直接用EXPLAIN ANALYZE命令统计sql真实的执行耗时

image-20240519134343957

所以我觉得还是参数的问题,但是arms是看不到参数的,所以用arthas进入容器

利用watch命令,在进行耗时过滤的同时,并打印出方法的入参出参

watch | arthas (aliyun.com)

image-20240519134608253

等了一段时间后,终于捉到了入参出参,然后代入到SQL中再重新EXPLAIN ANALYZE,确实慢的离谱

image-20240519135155416

好叭,问题查到了,SQL太慢了,该怎么优化呢?

一开始想着缓存替代,虽然有那么点数据不一致性,但是这个业务也能接受;

但后来分析了下这个参数,他没必要走这个查询,也就是说没必要去执行这个SQL

因为这个查询也是个配置化的东西,所以针对这个参数,可以直接去掉这个配置,这样就可以省略这段的SQL耗时了


优化2

在优化1中,我们可以看到,因为参数的特殊性会导致接口的耗时突然形成大尖刺,但还有一些中等尖刺存在,很显然还有别的影响耗时的因素。

再找条中等尖刺Trace看看

image-20240519140310566

image-20240519140351683

尼玛,又是条SQL,尬住了

image-20240519140430282

这个倒还好,结合代码看了下,是固定参数的查询,不用再自己watch捉参数了

老规矩,代入参数EXPLAIN ANALYZE分析下,还真是300多ms

image-20240519140804686

那咋办嘛,又要优化sql,hhh,真是跟sql过不去了

结合代码看看啦

梳理下那块的业务逻辑,是需要查询用户有没有领取过这个券,所以很简单的办法,我们只需要count一下就ok

而上面那个sql不仅联表查询了,而且还把两个表的大部分参数都查出来了,并且传参也不合适,没有利用到联表查询字段的索引进行数据扫描过滤,一切的一切累加起来,导致这个sql成为了一个慢SQL

所以优化后,处理很简单,单表查询 + count(*) + 走索引,快的离谱!

image-20240519141806099

image-20240519141829347

优化3

在排查上面优化2的时候,发现了一个问题

优化2的参数下,虽然会有300多msSQL耗时,但整体接口却可能还是存在1s+的耗时情况,这个就比较离谱了,因为我以为只有优化1的参数会导致这种情况,所以我用到了下面这个

最终发现下面这个耗时😒

image-20240519132239423

尼玛,是有点离谱啊,等锁等了这么久,这是超大大耗时尖刺啊!!!

为什么呢?

这又得跟我很久之前做的一个优化相关了,很久之前做过一些逻辑收拢

怎么理解呢?

重复代码太多了,让各个逻辑上游调用同一个method,同时还能利用JIT热点代码缓存优化,这不是yyds

image-20240519143330701

但是这个回旋镖终究还是打到了我自己

image-20240519143402341

因为逻辑收拢后,是做了一个 uid维度的分布式锁的,防止并发情况,giao!

但是随着业务的发展,这个并发冲突导致获取不到锁阻塞的场景出现频次会增高,所以就有了如上图所示的获取分布式锁,等了快四十秒,这不得枪毙我好几次 哈哈哈哈(开玩笑一下~

所以结合业务逻辑来看,我们是可以降低锁粒度的,uid维度锁粒度还是太粗了

所以最后改成了,uid + 业务唯一属性值做的分布式锁,这样冲突就是大大降低,耗时也能大大降低!


最终效果

最终以每天耗时来看,效果就如下啦,这线看着真舒服,😋,总算是把这份压力化解咯~

image-20240519143949923


总结

这次接口耗时的排查相比于之前我做的一些耗时优化还是蛮有意思的

之前无非是一些同步改异步的优化,此次不仅是结合业务逻辑做了一些SQL的优化,还认识到了锁粒度如果过粗,在高并发环境下的锁阻塞问题是十分严重的。

我是 Code皮皮虾 ,会在以后的日子里跟大家一起学习,一起进步! 觉得文章不错的话,可以在 掘金 关注我,这样就不会错过很多技术干货啦~