线上CPU飙高如何处理?

一、背景
某一天下午业务高峰期,突然收到线上服务CPU冲高,线程池被打满,几分钟之内,服务很快进入假死状态,系统频繁重启,客户反馈小程序或APP各种系统异常。

二、应急过程
1)运维确认前天晚上是否有版本变更,回退版本重启启用,发现系统仍然告警,排除版本引起的故障。
2)收到线上CPU和线程池打满的告警后,从线上dump线程运行情况,开始定位问题。
3)服务动态扩容CPU和内存,调整JVM启动参数,G1启动内存调整为6G。
4)redis收到频繁告警,CPU使用率达到100%,流量监控1.8G/s。
5)追踪发现业务上线了某个功能,导致redis流量暴增,系统接口响应非常慢,线程很快被打满,迅速通知业务下线功能。
6)系统恢复正常。

三、原因分析
1)业务方推广上了某功能,导致应用的流量大了3倍,QPS达到8000/s,后分析代码发现,之前某折扣策略规则都是存在redis中,
后面上的新业务,策略规则中有一个AOI的维度有600个,导致一条策略的报文大小大概为60kb,这样的策略,运营上了14个,
当业务高峰期,大流量下请求redis,导致redis cpu飙升非常快,带宽很快被打爆,而业务系统对redis依赖很重,接口请求都被redis拖垮
响应越来越慢。
2)应用节点虽然full gc很少,但是young gc非常频繁1s达到3次,严重影响了系统性能。

四、事后改进措施
1)调整应用JVM大小及GC参数
2)应用节点CPU及内存扩容
3)考虑到折扣策略数据量没那么大,针对redis 大key,优化缓存读写策略,引入本地+redis的二级缓存,优先读取本地缓存,减少对redis的冲击
3.1) 在应用启动的时候, 将折扣策略信息预热到本地缓存
3.2) 管理后台上架或下架策略的时候,广播消息,刷新二级缓存
4) 本地缓存失效,在应用中打印告警日志,配合监控系统告警研发同学,人工介入,触发job,重刷缓存,保存本地缓存能快速恢复
5) 接口从缓存中获取的策略json字符串转为大对象,在高并发下,这一步操作非常耗时并且很容易触发young gc,优化为全局静态变量存放大对象,减少tolist对象转换操作
例如:
String discountStr = discountCacheService.findStrategyList();
//这一步非常耗时
List<StrategyListDTO> strategyList = JsonUtil.toList(discountStr, StrategyListDTO.class);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值