生产故障排查——高并发时的懒加载逻辑导致应用无法响应

故障现象

  生产环境上线新功能,我们采用灰度的方式足台更新服务节点,保证能持续提供服务。最近一次更新发现在节点启动完后,接入流量运行小会节点会出现无法响应的情况,此时cpu占用非常高,而且切断流量后也无法恢复。担心是新上线逻辑问题,马上执行回滚操作(更新回之前的稳定版本),但是,回滚后重新启动接入流量也还是出现同样的问题。

问题分析

  导出问题节点故障时的jstack日志,

jstack -l pid

  jvm线程cpu情况分析

top -Hp pid

  发现大量请求卡在需要分配内存的代码片段,于是分析gc情况,发现一直在持续的进行full GC,没法提供服务。
  结合jstack日志分析代码逻辑,发现大量线程都在初始化一份接口映射需要的基础数据。从代码逻辑分析,首次请求时,会先判断这份数据是否存在,不存在则会执行初始化。编写这段代码的开发人员意图应该是想在使用到的时候再加载,相当于对数据进行懒加载处理。但是,没有考虑到如果大量的请求同时进入到这个逻辑,将会并发初始化这份数据,导致cpu使用暴涨,内存开销巨大,从而引起上面的故障现象,jvm持续full GC无法恢复。
  分析清楚原因后,问题处理就比较容易了,有两种方案:

1、将初始化数据的逻辑放入启动的阶段进行;
2、对初始化数据的逻辑做线程锁控制,大量线程请求,只会有一个线程获取锁去执行数据初始化的逻辑,其他线程阻塞等待初始化完成。

  为了尽快恢复服务,我们采用第二种方案先紧急修复。修复后,重新更新测试,问题解决。

总结

  平时开发中,很多时候也会采用数据懒加载的方式,在需要使用的时候再加载,避免多余的初始化浪费。但必须注意线程的控制,避免并发执行这些初始化操作。
  同时,上面的问题现象还有个疑问点:为什么以前更新服务未出现问题(有问题的代码已经运行很久)。猜想应该和最近新上线大量用户有关,以前偶尔也会出现,由于没重视而忽略了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值