线上流量突增百万高可用保障方案

一:事前预防

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、问题分析及解决办法

问题分析:

  1. 运营当天配置了XX策略,每条策略大概有XXX个规则;
  2. 之前的策略数据都是存储在redis中,所以运营配置XX条策略生效以后,redis接收到的报文瞬间变得非常大,策略key快速升级为大key,从1kb变成60kb,客户端频繁请求redis大key,流量高达1.8G/s,很快系统的http线程池被打满请求无法响应,系统进入假死状态。

解决办法:

  1. 优化edis大key:事发当晚,针对redis大key场景,引入本地缓存作为一级缓存,优先从本地存读取数据,减少对redis中间件的压力,优化后redis运行比较平稳
  2. 增加系统异常预案处理:在配置中心增加动态关闭接口的开关,一旦出现系统将不可用的情况。立即打开开关,进行人工降级并返回兜庭数据,等待系统资源正常后再打开开关。

3、总结与反思

1、研发侧

  1. 对redis重度依赖,redis有细微的抖动,服务接口响应时间波动非常大,系统风险大;
  2. redis使用不规范,没有提前对redis大key作出预判,导致面对突发流量,系统扛不住;
  3. 没有形成一套标准的高井发和高稳定性的架构设计评审方案,由于xxx系统属于核心系统,每天请求的OPS很大,所以对于系统的稳定性设计要求极高,可能设计方案出现一点疏忽就会影响系统整体的稳定性;
  4. 性能压测没有真实模拟线上数据,导致压测结果有偏差,不能对研发同学优化性能做到精准支撑;

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对系统进行扩容处理,同时增加审批的流程,比如运营负责人审批后才能上线策略;

    建议运维上线策略采用灰度发布的方式,发布当天,运营密切关注数据是否正常,确定没问题后第二天再推向全网用户

猜你喜欢

转载自blog.csdn.net/quanzhan_King/article/details/130649574
今日推荐