复盘大促宕机生产事故,重新审视新接手的项目。
1. 背景
A部门大部分顾问离厂,自有员工接手系统,被抽掉入A部门某组;
核心系统主要技术栈:Nginx(负载) + Lua(参数处理/请求分发) + JBoss(业务处理) + Redis(缓存) + Solr(底层存储)
818公司大促活动,18号凌晨系统QPS达到峰值22000,底层Solr集群被打挂,上层应用系统崩溃。
紧急重启Slor集群、应用系统;应用系统间歇性宕机,先后重启了三次才恢复。
2. 应用系统启动失败
重启应用时,值班人员没有切断前端访问流量;
这边应用在重启,那边大流量不停的访问,导致应用解压缩war包失败,出现大量异常,最终超过文件句柄连接数,导致重启失败。
最后一次重启成功,是按照标准流程来的,断开流量、重启应用、启动成功后,再接入流量。
3. 复盘分析
3.1. 业务
818之前三个版本的需求,业务扩张非常庞大,主站内各个页面、活动页,增加了四十几个调用方。
虽然818之前经历了618大促,但是由于618时,外部接口调用没有全部放开,所以618的QPS只有6000左右,直接导致了818后面预估容量出现较大误差。
3.2. 预估/压测/评审
业务扩张之后,系统没有一个全面准确的流量评估,流量应该结合 上游调用系统、业务/运营、产品 三方结果 综合评估,并包含一定的流量放大(冗余量)。
大促前的压测不重视、不全面、不准确。
3.3. 技术层面
3.3.1. solr
solr集群脆弱,最大承受3000TPS,818峰值6000,导致solr崩溃;后台程序,在高峰时刻(八点、十二点)有定时任务,向solr集群写数据,消耗、占用很大一部分资源。
3.3.2. 缓存
3.3.2.1. 缓存问题
在最后一个发布版本中,错误更改了一部分的本地缓存策略,导致部分场景本地缓存失效。
(当时评估不会对业务有大影响,忽视了对性能影响,而且错过了发布周期,所以带着该问题继续运行)
程序中做了二级缓存,一级是本地缓存、二级是redis缓存;缓存的数据内容是从solr查出来的原数据,没有做去重等业务处理。
3.3.2.2. 缓存穿透
很多业务场景都与会员相关,当时只顾着对这部分业务加Redis缓存;遗漏了其他的业务场景。
在零点峰值时,很多流量打到了solr集群的原因,是有很多新用户,没有做缓存。
3.3.3. 日志
临时接手该应用短,期间一直在进行业务需求开发,没有时间梳理代码。
后期监控发现,老代码中有很多日志信息,大量日志信息输出影响IO性能。
4. 优化
重新评估系统抗压能力
对所有接口进行混压,压测要贴近生产。
solr集群切换到Elasticsearch集群
后台定时任务逻辑优化
本地缓存策略全面排查
二级缓存的数据进行梳理优化
新用户做临时会员号/设备号,走缓存
梳理/删除 老代码中无用、耗费性能的代码
流控