一:事前预防
1、预估系统瓶颈
1.1 梳理核心接口
- 按调用量梳理Top100
- PM按业务重要等级梳理下端可能起量的接口
- 输出终版的接口文档
1.2 评估核心接口最高的TPS
- 测试环境模拟生产环境数据
- 核心接口进行全链路压测
- 输出核心接口性能报告
2、系统高可用保障措施
2.1、核心接口限流治理(不依外部接口)
- 应用集成sentinel
- 应用对应的接口接入限流
- 打印限流日志(便于设置告警)
- sentinel管理端配置接口限流闯值(参考:接口最高的TPS*20%)
2.2、核心接口超时治理、熔断兜底治理(依赖外部接口)
- 应用集成sentinel
- 设置调用外部请求超时时间 (默认为3s)
- 打印超时日志(便于设置告警)
- 应用对应的接口接入熔断
- 跟业务确认好兜底方案
- 打印兜底日志(便于设置告警)
- sentinel管理端配置接口熔断闽值(按响应时间RT、异常数、异常比例设置)
2.3、监控告警
- 接口调用量突增告警(基于监控能力)
- 接口限流告警(基于打印的限流日志配置)
- 调用外部接口超时告警(基于打印的超时日志配置)
- 业务监控(例如,活动发放监控,券发放监控,积分发放与商城积分兑换监控
- 应用Job,涉及事务操作支持幂等
2.4、应急预案准备
- 梳理核心接口异常风险点(主要评估可降级的关键地方)
- 非业务手工降级(配置disconf动态配置开关手工降级)
- 接口层面直接降级(配置disconf动态配置开关手工降级)
2.5、每日健康度巡检(每天早上9点)
2.5.1 错误日志检查
2.5.2 应用指标检查(CPU、内存fullgc、繁忙线程数)
2.5.3 中间件指标
-
redis : cpu,内存使用率,每秒命令写入数,redis慢查询
-
kafka:生产速率,消费速率,kafka积压情况
2.5.4 数据库指标
- cpu:内存使用率, IO, 慢SQL
2.2.5、 接口指标
-
APM8大于1s接口
-
核心接口调用量峰值是否飙升
2.2.6 核心业务功能巡查(比如会员中心、查券、查询折扣)
2.5.7 异常监控告警日志原因检查
二: 事中处理
1、应用重启
-
CPU打满
-
线程池打满
2、应用升配
应用升配,中间件升配,数据库生胚
- CPU升配(比如8慈升到16核)
- 内存升配(比如8G升到16G)
- 应用内存升配后JVM参数优化
3、扩容
- 应用扩容 : 应用节点扩容(8节点-12节点)
- 中间件扩容 : redis扩容(redis增加主从节点) kafka扩分区(增加kafka分区)
4、流量控制
- disconf开启应急预案接口关闭配置开关,快速切断流量
- sentinel管理端修改接口限流闻值(比如从之前的100降低到50),限制流量
5、版本回滚
- 配置回滚(挂载和Disconf配置)
- 应用版本回滚
6、业务(影响系统性能)下线
- 业务下线
- 知会产品或运营
三: 事后复盘
以一个P0级别故障项目复盘为例,说明
1、 事件回顾
-
1、x月x号xx:xx分(比如3月14日 20:20分)运营人员上线XXX策略,其中多条优惠策略是面向全网用户生效;
-
2、x月x号xx:xx分,研发突然收到系统大量接口告警,研发迅速开始查询日志排查问题;
-
3、x月x号xx:xx分,运维反馈有部分应用节点不可用,运维开始对应用cpu和节点数进行水平扩容并且串行重启动态优惠系统所有节点;
-
4、x月x号xx:xx分,xx系统反馈xx业务出现大量下滑,启动P0故障;
-
5、x月x号xx:xx分,系统部分节点出现自动重启,研发和运维继续监控检查系统各项指标;
-
6、x月x号xx:xx分,通过监控发现redis出现一些大key,流量非常高,达到1.8G/s,经排查是新上业务策略报文太大导致redis出现大key;
-
7、x月x号xx:xx分,运营下架相关业务策略,系统恢复正常。
整个故障持续时间接近20分钟,间接影响收入XXX万,定级为P0故障
2、问题分析及解决办法
问题分析:
- 运营当天配置了XX策略,每条策略大概有XXX个规则;
- 之前的策略数据都是存储在redis中,所以运营配置XX条策略生效以后,redis接收到的报文瞬间变得非常大,策略key快速升级为大key,从1kb变成60kb,客户端频繁请求redis大key,流量高达1.8G/s,很快系统的http线程池被打满请求无法响应,系统进入假死状态。
解决办法:
- 优化edis大key:事发当晚,针对redis大key场景,引入本地缓存作为一级缓存,优先从本地存读取数据,减少对redis中间件的压力,优化后redis运行比较平稳
- 增加系统异常预案处理:在配置中心增加动态关闭接口的开关,一旦出现系统将不可用的情况。立即打开开关,进行人工降级并返回兜庭数据,等待系统资源正常后再打开开关。
3、总结与反思
1、研发侧
- 对redis重度依赖,redis有细微的抖动,服务接口响应时间波动非常大,系统风险大;
- redis使用不规范,没有提前对redis大key作出预判,导致面对突发流量,系统扛不住;
- 没有形成一套标准的高井发和高稳定性的架构设计评审方案,由于xxx系统属于核心系统,每天请求的OPS很大,所以对于系统的稳定性设计要求极高,可能设计方案出现一点疏忽就会影响系统整体的稳定性;
- 性能压测没有真实模拟线上数据,导致压测结果有偏差,不能对研发同学优化性能做到精准支撑;
2、底盘运维侧:
目前我们所有的应用都已经上云,对集团底盘能力依赖较重,但集团提供的排查工具比较粗糙,没有顺手的工具可用,这里总结了几点如下:
-
JVM层面:
获取dump线程文件:每次都需要找运维帮忙手工dump线程文件,人工介入比较慢。
定位详细的性能瓶颈:目前实时在线分析应用指标的性能问题比较难,底盘提供的grafana指标监控,只能分析粗略的结果,不能准确定位是什么原因导致CPU飘高、频繁full gc、http线程被打满,排查问题周期较长。
-
中间件层面:
redis工具缺乏:目前底盘没有的redis慢查询、热Key、大key等监控工具,导致redis线上排查问题很困难
运维没有开放底层中间件与数据库的监控告警给业务研发,导致业务研发不能及时收到告警作出合理的响应。
3、产品运营侧:
- 产品侧:负责系统的产品同学经常换人,系统缺乏沉淀,而且系统逻辑复杂度很高,新人熟悉底层逻辑的时间通常很久,这样就会导致出需求的时候考虑不完善漏掉一些核心逻辑。
- 运营侧:运营同学上架策路节奏过快,策略上线后经常面向全网用户,如果出现问题,会引起大量客诉,风险高
4、行动与结果
1 研发测
- 输出一套标准的redis使用规范,包括redis存储规范、redis热key解决方案、redis大key解决方案,并在部门内进行导,避免其他组坑
- 开发redis热key、大key监控与告警的工具并且集成到鹰眼监控平台,方便部门研发人员第一时间定位问题
- 后续产品需求进入研发前,必须事先有严格的技术方案评审,研发同学必须输出架构方案设计图、接口详细设计、数据库设计、性能与安全设计、服务限流与降级配置、监控告警配置、预案设计,文档沉淀到CF,由各组PM主导,相关的研发和测试人员必须参与
- 性能压测必须输出一套统一的标准,压测的测试场景与线上高度还原,接口如果达不到业务要求上线的标准,测试同学通过邮件报备,与PM商量后是否延期需求,等研发优化完达到指定的性能标准后再上线
2 底盘运维侧
-
JVM层面:建议获取dump线程文件自动化,运维可以在集团云提供一个可视化页面,研发同学可以随时下载系统异常时刻dump线程文件
建议集团云在k8s容器集成Arthas性能分析工具,很多互联网大厂在使用,可实时在线分析应用相关指标,非常方便。
-
中间件层面:建议运维开放中间件和数据库的监控给业务研发,确保研发第一时间接收到信息进行处理,及时消除潜在的系统风险;
建议底盘开发redis慢查询和告警功能,可以串联skywalking分布式链路工具一起输出,这样排查性能问题非常有用
3 产品运营侧
-
产品侧:建议产品同学尽可能固定并且有备份同学,稳定的团队有利于系统长期、持续的规划和沉淀系统还有不少前任产品留下来的业务债务;
建议产品同学预留足够的时间优先处理这些债务,否则做的越多销的越多,我理解现在的慢是为了将来的快,欲速不达,
-
运营侧:后期上策略建议邮件抄送,建议说明策略面向的用户量和生效时间,便于研发提前监控数据以及是否根据系统支撑的最大QPS对系统进行扩容处理,同时增加审批的流程,比如运营负责人审批后才能上线策略;
建议运维上线策略采用灰度发布的方式,发布当天,运营密切关注数据是否正常,确定没问题后第二天再推向全网用户
网友评论