稳定性方案-总览

 

引言

为了更好的推动酒旅各业务系统稳定性建设,从系统设计上减少故障发生,尽早发现问题避免升级为故障,更快更好的处理故障,以及从每一次故障中学习倒逼我们改进系统架构,我们制作了本方案。

本方案希望作为一个“精炼的高可用系统方法论”+“美大酒旅最佳实践”,用以指导我们的系统设计,或针对当前系统进行Review,发现短板并进行补齐。本方案共分六个部分。

第一部分高可用系统原则,关注怎么从系统设计的角度来保证稳定性

第二部分日常巡检,关注怎么通过经常性的系统检查来发现问题,审视当前的系统是否存在隐患

第三部分异常检测,关注怎么通过合理的指标设置和监控报警配置,及时及早的发现问题,定位故障原因

第四部分故障处理,关注怎么在故障发生时,能够通过简单可落地的步骤来及时止损,缓解故障

第五部分故障总结,关注怎么在故障发生后,能够通过系统的方法论和思考,来找到问题的根源,并推动我们升级系统

第六部分酒旅特有问题和具体例子,主要针对酒旅业务特点,进行补充说明和举例,这部分内容暂时候补

一、高可用系统

影响系统稳定性的因素,从系统层面划分为两大方面:

因素

说明

方案

外部因素

依赖的系统不稳定(返回错误,超时)

依赖软硬件损坏或者故障(云服务、SDN、物理主机)

超过系统极限能力的流量等

隔离 + 监控

冗余 + 监控

可流控 + 监控

内部因素

系统设计不合理(产品设计和架构设计)

系统实现有Bug

操作流程不规范,缺乏预案(开发上线流程和异常处理流程)等

高可用架构设计

回滚

标准流程SOP等

 

隔离

确保任何局部问题不影响全局。隔离一般分:

  • 业务隔离(服务拆分)。比如首页、详情等浏览服务,与下单、支付交易服务拆分隔离。交易系统下单、支付回调、退款等多个子服务拆分

  • 异常隔离(交互隔离)

    • 设置合理的超时和重试机制来规避短时的依赖故障。具体设置参考专项梳理部分

    • 通过熔断机制(依赖降级)来规避过多的依赖故障

  • 部署隔离

    • 在线、离线隔离

    • 核心、非核心隔离

    • B、C端隔离

    • 不同功能特点业务隔离。比如主交易,秒杀隔离

    • 易变、不变隔离,动静分离等

冗余

冗余的核心是N+1部署,避免单点故障,要点是做到全链路冗余,多机房部署:

分层服务

原则

接入API(首页、频道、列表等)

冗余部署,水平扩展

各业务服务(POI、产品中心、搜索、筛选、下单、支付回调、订单详情等)

冗余部署,水平扩展

各基础服务(Mysql、DB中间件、Tair、Redis、MQ、ES)

冗余部署,提供多副本存储,数据一致性

数据冗余

数据多备份,数据一致。可以快速切换

可流控

可扩容:能进行分流扩容的前提是服务设计要做到可水平扩展,无状态服务水平扩展相对容易。

可降级:是利用有限资源,保障系统核心功能高可用、有损的架构方法。(基础:系统具备可扩展性、故障隔离、服务拆分和治理。原则:单一职责和故障隔离原则)

先梳理核心业务流程(核心高可用,级别越低,可用性要求越低),最终明确了服务依赖关系(区分核心依赖和非核心依赖)和上下游SLA指标。

服务依赖关系

举例

上下游SLA

上游服务(组合服务)

常见系统:订单中心,搜索服务。降级方案:限流降级方案和开关;按照用户质量,将高风险用户、爬虫优先降级;按照上游系统等级,将低级别系统的资源调度到高级别系统。

根据上游确认的SLA,超出调用量阈值的,触发限流降级开关;

核心依赖故障,快速失败

非核心依赖自动降级

基础服务

(下游服务)

常见系统:产品中心、促销系统。降级方案:梳理依赖的影响程度和范围;设计候选降级方案和开关;通常可以使用DB临时替代缓存提供查询功能;或者使用缓存提供库存扣减,数据库异步同步数据。

根据下游确认的SLA,结合最近的可用率、资源使用率、耗时等统计、监控信息,切换到备选方案,或恢复到常规方案。

酒旅侧降级方案可以考虑接入度假团队开发的弹性工程 - 构建弹性系统,支持大象一键降级和自动降级。https://resilience.trip.meituan.com/

可限流:限流作为服务的主要功能,能从Appkey分组、AppKey、用户、商家四个维度进行流量控制,当流量超过设置阈值时,服务会直接返回错误信息(错误码403,有明确的因流控被拒的错误信息)给请求者,不会再继续调用后端服务,从而保护了后端服务不被攻击。同时我们还应具有精准流控,实时生效的特点。

流控支持两种限流模式:控制速率和控制并发。目前提供限流的主要有:外卖的限流平台 流控系统, 以及度假侧弹性工作台 弹性工程 - 构建弹性系统 

 

可回滚

服务可回滚,不仅依赖底层发布系统的功能性支持,而且要从流程和设计上支持

服务可回滚需要做到以下几点:

  1. 应用管理规范:应用版本化(工程、接口)、合理的分支策略(Gitflow工作流)、代码审核、目录结构(统一)

  2. 权限管理规范:系统权限、服务权限。

  3. 配置变更规范:系统部署(自动化、镜像)

  4. 发布策略规范:发布时间(避开峰值、QA评测)、发布工具的集成化程度。

  5. 服务要支持回滚:数据改动(设计和开发时候要考虑好兼容性,必须具备回滚脚本)、变更删除数据(分成两步,第一步上线验证,第二步删除数据)、变更发布后其他系统已经依赖无法回滚(开发一种版本无关的服务,可以强制对数据进行同步) 

 

二、日常巡检

容量规划

容量规划的本质是资源管理。可通过如下步骤进行规划:

  • 设定考核的指标类型和健康阈值:比如tps/qps为多少,或者是CPU、内存使用量

  • 依靠监控系统获取到线上业务的“指标峰值”:V

  • 通过压测,得到集群在满足考核指标时,系统的实际指标值,R

  • 根据公式计算现有容量比例:C = V/R *100%。C的参考值见“专项梳理”->“容量指标”->“参考阈值”部分。

  • 根据具体需求规划容量:

    • 日常情况,线上容量应该是日常峰值指标的2~3倍

    • 有新的大型活动、促销或者重大节日,线上容量指标应该重新评估,达到日常峰值的5倍以上

全链路压测

全链路压测,是对前后端服务、缓存、存储、中间件等一系列组件整体的评估手段,默认在线上进行

  • 目的:排查性能瓶颈,测试系统容量,并指导各种阈值设定

  • 操作:

    • 梳理压测路径,计划压测方案

    • 压测数据构造:通常使用线上的历史数据,脱敏后成为压测数据

    • 实施压测

      • 读操作可直接使用压测数据

      • 写数据的情况,需要考虑对脏数据进行隔离,或者保证可清理

    • 制作压测报告

  • 总结:对压测过程中出现的问题进行总结,让整个系统更加量化

故障演练

  • 目的:

    • 验证演练内容,验证报警响应机制

    • 让团队成员熟悉线上故障的操作流程

    • 完善故障处理SOP

  • 操作步骤:

    • 明确演练内容,并根据内容评估影响范围,做好预案

    • 制作故障模拟手册,记录执行每一步的操作步骤和预计效果

    • 准备好故障解决SOP手册

    • 按照故障模拟手册进行故障模拟,生成实际故障,并通过监控和报警等手段记录实际故障现象

    • 根据SOP手册对故障进行解决:

      • 如果产生的故障SOP可以快速定位,就按照SOP手册进行故障解决;

      • 如果产生的故障SOP不能解决,则需要定位并解决故障,并将方法记录在案,完善SOP

  • 总结:对演练中出现的不符合期望的问题进行case study,完善系统,完善SOP

专项梳理

关注系统的重点指标,持续改进系统的性能和稳定性

  • 容量指标:用来指导我们进行容量管理,比如缩容或者扩容

    • 系统级指标:应用及数据的CPU、内存、IOPS、缓存命中率、GC、带宽

    • 业务级指标:业务销售额、重要接口和服务的响应时间、错误日志、DB的慢查询、服务调用超时率等

    • 参考阈值:可以使用前面定义的容量比例C值,作为容量指标的统一衡量,参考阈值如下:

      (说明:单机房应用的阈值是根据经验;双机房应用的阈值低是因为要考虑一个机房故障时,另一个机房抗所有量的情况;三机房应用,坏一个机房的可能性是有的,但两个及以上都坏的可能性非常小,因此阈值介于单机房和双机房应用之间)

  • 超时:是服务容错的一种方式

    • 原则:如果存在多级依赖关系,如A调用B,B调用C,则超时设置应该是 A>B>C

    • 超时时间的设置:调用一个服务的超时时间可以是该服务在tp999下响应时间的2.5~10倍,且一般不超过10秒

    • 服务上下游之间要进行SLA确认:依赖方要驱动被依赖方进行SLA的改进,而被依赖方也有责任改进,并最终得到双方认同的SLA

  • 重试:是服务自我恢复的一种形式

    • 重试的前提:对一个服务可以进行重试,其前提是该服务具有“幂等性”,比如读请求,或者保证了幂等性的写请求

    • 需要重试的场景:通常来说重试发生在上游对下游数据具有强依赖的场景。比如:

      • 使用中间件客户端的时候可以重试

      • 整个请求服务的入口可以重试(比如Web应用中,nginx对jetty的请求)

      • 服务链条中的服务不建议重试

    • 重试的策略:

      • 重试的次数:一般1~2次 (数据库或medis的连接池这样的中间件客户端可以重试两次;对一般可重试的服务请求,只重试一次)

      • 重试的时间间隔:可以依次递增翻倍 


三、异常检测

介绍

监控指标分为以下三种:核心基础设施监控(CIM)、应用级别监控(ALM)以及服务质量监控(SQM)。其中CIM包括:CPU的平均使用率、CPU峰值的持续时间、内存的平均使用情况、带宽的输入输出等情况;ALM包括:JVM进程的内存、内部线程的数量、磁盘IO、索引的读取/写入操作等;SQM包括:请求所需的最大时间、请求所需的平均时间、每分钟请求的平均速度、每天峰值的请求速度、订单数、查询数、请求日志以及请求错误数等。

目标

  • 根据小问题预测是否可能演变成大问题

  • 判断系统是否出现问题

  • 调查哪里出现问题

  • 确定是什么问题

核心关注点

过多产生噪音,过少产生遗漏

报警设置思路

  • 报警分级:根据监控项的重要程度,将警报分级

    • 高:必须立即处理;报警方式:大象,短信,电话通知;报警项建议值:3~10项

    • 中:需要关注,可能不需要立即处理;报警方式:大象或者邮件;报警项建议值:几十项

    • 低:需要引起注意,不需要立即处理;报警方式:日常值班观察或者邮件;报警项建议值:上百项

  • 报警阈值设置

    • 下策:设置阈值,定期复盘修改阈值,达到阈值报警

    • 上策:根据过去一段时间核心指标的方差,明显偏于方差值报警,示例:过去连续几十次相同时间的监控项的方差统计;监控曲线的斜率变化等

  • 最佳实践

    • 高级别:用户体验和核心业务指标,从用户视角观察,影响到用户操作的问题或者业务核心的指标,示例:订单数,支付数,C端延时等

    • 中级别:系统指标,描述系统健康状态的指标,示例:CPU,MEM,JVM等

    • 低级别:应用指标,用来追踪应用系统问题的指标,示例:异常日志,调用链,方法调用时间

使用方式

根据用户体验和核心业务指标报警判断系统是否出现问题  →  通过查看系统指标定位是哪里出了问题 → 通过应用指标判断是什么原因导致问题  → 解决并修复问题

 

四、故障处理

原则

  1. 及时止损:例如上线导致故障,第一时间应该快速回滚,及时止损,而不是追问题改代码

  2. 无脑预案:因为在故障发生时,最困难的就是知道“发生了啥”,“该干啥”,任何“如果xxx就xxx,如果yyy就yyy,不然就zzz”的方案都是不可执行的

  3. 工具化、平台化:预案不能依赖特定的人,例如降级要有一键开关,而不是需要某个人去x平台改个参数,y平台改个超时

  4. 及时通报:及时对外同步故障的影响,跟进人,修复进度,便于相关团队知晓、协助

  5. 经常演练:没有经过经常性演练的预案==没有预案

手段

手段

适用场景

风险

建议

回滚

  1. 流量没有突增

  2. 依赖没有明显故障

  3. 近期有上线

  1. 慢(全量回滚)

  2. 可能产生脏数据等

  1. 善用灰度,避免全量发布、全量回滚

  2. 新功能要有feature flag,便于有问题及时关闭

重启

  1. 外部因素没有明显变化

  2. 服务本身资源耗尽,如连接池、内存耗尽、死锁等

  1. 治标不治本

  1. 与限流、降级、扩容等手段结合,例如先限流、扩容,再重启,避免重启一次,打挂一次

扩容

  1. 外部流量突增

  2. 服务本身扛不住

  3. 下游服务正常

  1. 慢

  2. 可能会压垮下游服务

  1. 与限流、降级结合,例如先限流,如果服务恢复,再同时上下游扩容

切流量

  1. 单机房故障(出口、单机、交换机等等)

  2. 双机房互备(任一单机房可以抗全流量)

  1. 可能会压垮另外的机房(如果容量有问题)

  1. 机房间彻底隔离,除了底层数据同步,不存在任何跨机房调用

  2. 出问题直接机房入口切流量

降级

  1. 内部故障

  1. 无

  1. 非核心依赖自动降级

  2. 业务功能模块手动降级

限流

  1. 外部流量突增

  1. 可能触发上游/用户疯狂重试

  1. 与上游熔断机制结合,例如app限制用户频繁刷新,上游服务调用失败主动熔断

最佳实践

发生故障时,及时明确三个问题:

  1. 最近有没有上线

  2. 外部业务流量有没有突增

  3. 下游依赖有没有明显故障

之后迅速采取止损措施:

  1. 如果有上线,第一时间回滚,排除上线导致的逻辑问题

  2. 如果业务流量突增,优先限流,保证一部分请求正常处理,然后迅速全链路扩容

  3. 如果下游依赖有明显故障,优先降级掉涉及该依赖的功能、模块,保证核心业务正常,再针对性的恢复该依赖

同时实时在SRE群通报问题处理进展,便于相关团队协助排查、处理问题

 

五、故障总结

CaseStudy

    原则

  • 描述事实,对事不对人

  • 寻根溯源,举一反三,避免局限在代码层面

  • 改进方案可落地执行,用系统解决,非意识流

    模板(含示例)

           酒旅CaseStudy模板

保障系统进化

    目标:类似故障不会再次发生

    实施建议

  • 针对故障暴露问题,从日常巡检、异常检测、故障处理三方面完善现有保障系统

  • 此类故障预案演练,保证预案有效

定期故障集剖析

    目标:量化分析全部case故障原因,针对性系统性改进

    实施建议

  • 周期:季度 or 月度

  • 主R:架构师 or 技术leader

  • 思路:
          全部study原因量化分析,建议按开发、测试、运维角度拆分并细化
          对主因制定改进方案,短期方案做到立竿见影,长期方案做到架构和开发流程改进

  • 示例:

 

六、酒旅特有问题和具体例子

(业务安全,比如反爬。流量分级与运营)

 

posted @ 2019-02-27 20:13  积淀  阅读(5)  评论(0)    收藏  举报