记一次系统性能调优发现的bug

现象:

系统即将上线,再做压力测试时,突然性能直线下降,原本几十ms的服务,性能下降了几十倍;

分析调用链日志,发现性能瓶颈全部集中在某一个微服务应用内;于是展开对该应用的分析;

分析过程:

1、在灰度环境(使用生产库)单独调用出现性能问题的服务,性能表现正常;由此可排除该服务使用的sql问题及索引问题;

2、查看生产应用的资源使用情况(cpu占用10%,内存占用达到90%)。

3、查看gc日志:有大量Full GC  Allocation Failure错误。

 (concurrent mode failure): 2804992K->2804991K(2804992K), 8.3314947 secs] 3111679K->3111637K(3111680K), [Metaspace: 113455K->113455K(1153024K)], 8.3316136 secs] [Times: user=8.02 sys=0.32, real=8.34 secs] 
2235.607: [Full GC (Allocation Failure) 2235.607: [CMS: 2804991K->2804991K(2804992K), 5.2187601 secs] 3111679K->3111636K(3111680K), [Metaspace: 113455K->113455K(1153024K)], 5.2188652 secs] [Times: user=4.98 sys=0.25, real=5.22 secs] 
2240.827: [GC (CMS Initial Mark) [1 CMS-initial-mark: 2804991K(2804992K)] 3111636K(3111680K), 0.1321992 secs] [Times: user=0.17 sys=0.00, real=0.13 secs] 
2240.959: [CMS-concurrent-mark-start]
2240.961: [Full GC (Allocation Failure) 2240.961: [CMS2242.818: [CMS-concurrent-mark: 1.854/1.858 secs] [Times: user=1.86 sys=0.00, real=1.86 secs] 

ps:堆内存划分为 Eden、Survivor (分两块)和 Tenured/Old 空间

GC前,young(eden+s0)的占用是100%,且从Allocation Failure可以看出old满了

由于young无法通过Young GC回收,升级到old,但old也满了就导致 Allocation Failure 触发Full GC,而且耗时达到8.3 secs!STW导致整个系统都暂停响应了。

GC后,young依旧没有变化,还是100%,是内存泄漏导致无法回收,系统OOM了。

还有些gc日志中,在GC后,young释放了资源,说明young增长过快导致young gc来不及回收,从而把old挤满;

这时又有新bug反应出来:某服务超时,不过从上面的分析过程来看,超时也是迟早的事。

根据上面的分析,应该是某个服务不断创建对象导致的。现在需要定位到底是哪个服务导致的。

检查期间的服务调用日志(其实应该先联系dba检查下系统慢sql)。

果然,发现有个千万级的表查询时条件中没有加用户id。

检查代码发现,mybatis写法:

select xxxx from xxxx
where 1=1
<if "a_no"!=0>
and a_no=#{a_no}
</if>
<if "b_no"!=0>
and b_no=#{b_no}
</if>

总结

1、长期:做代理层的优化,禁止全部查询,避免这样的sql再度出现

2、短期:检查所有类似写法的,要在数据层做好限制。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值