稳定性方案-总览
引言
为了更好的推动酒旅各业务系统稳定性建设,从系统设计上减少故障发生,尽早发现问题避免升级为故障,更快更好的处理故障,以及从每一次故障中学习倒逼我们改进系统架构,我们制作了本方案。
本方案希望作为一个“精炼的高可用系统方法论”+“美大酒旅最佳实践”,用以指导我们的系统设计,或针对当前系统进行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,有明确的因流控被拒的错误信息)给请求者,不会再继续调用后端服务,从而保护了后端服务不被攻击。同时我们还应具有精准流控,实时生效的特点。
流控支持两种限流模式:控制速率和控制并发。目前提供限流的主要有:外卖的限流平台 流控系统, 以及度假侧弹性工作台 弹性工程 - 构建弹性系统
可回滚
服务可回滚,不仅依赖底层发布系统的功能性支持,而且要从流程和设计上支持
服务可回滚需要做到以下几点:
-
应用管理规范:应用版本化(工程、接口)、合理的分支策略(Gitflow工作流)、代码审核、目录结构(统一)
-
权限管理规范:系统权限、服务权限。
-
配置变更规范:系统部署(自动化、镜像)
-
发布策略规范:发布时间(避开峰值、QA评测)、发布工具的集成化程度。
-
服务要支持回滚:数据改动(设计和开发时候要考虑好兼容性,必须具备回滚脚本)、变更删除数据(分成两步,第一步上线验证,第二步删除数据)、变更发布后其他系统已经依赖无法回滚(开发一种版本无关的服务,可以强制对数据进行同步)
二、日常巡检
容量规划
容量规划的本质是资源管理。可通过如下步骤进行规划:
-
设定考核的指标类型和健康阈值:比如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等
-
低级别:应用指标,用来追踪应用系统问题的指标,示例:异常日志,调用链,方法调用时间
-
使用方式
根据用户体验和核心业务指标报警判断系统是否出现问题 → 通过查看系统指标定位是哪里出了问题 → 通过应用指标判断是什么原因导致问题 → 解决并修复问题
四、故障处理
原则
-
及时止损:例如上线导致故障,第一时间应该快速回滚,及时止损,而不是追问题改代码
-
无脑预案:因为在故障发生时,最困难的就是知道“发生了啥”,“该干啥”,任何“如果xxx就xxx,如果yyy就yyy,不然就zzz”的方案都是不可执行的
-
工具化、平台化:预案不能依赖特定的人,例如降级要有一键开关,而不是需要某个人去x平台改个参数,y平台改个超时
-
及时通报:及时对外同步故障的影响,跟进人,修复进度,便于相关团队知晓、协助
-
经常演练:没有经过经常性演练的预案==没有预案
手段
|
手段 |
适用场景 |
风险 |
建议 |
|---|---|---|---|
|
回滚 |
|
|
|
|
重启 |
|
|
|
|
扩容 |
|
|
|
|
切流量 |
|
|
|
|
降级 |
|
|
|
|
限流 |
|
|
|
最佳实践
发生故障时,及时明确三个问题:
-
最近有没有上线
-
外部业务流量有没有突增
-
下游依赖有没有明显故障
之后迅速采取止损措施:
-
如果有上线,第一时间回滚,排除上线导致的逻辑问题
-
如果业务流量突增,优先限流,保证一部分请求正常处理,然后迅速全链路扩容
-
如果下游依赖有明显故障,优先降级掉涉及该依赖的功能、模块,保证核心业务正常,再针对性的恢复该依赖
同时实时在SRE群通报问题处理进展,便于相关团队协助排查、处理问题
五、故障总结
CaseStudy
原则
-
描述事实,对事不对人
-
寻根溯源,举一反三,避免局限在代码层面
-
改进方案可落地执行,用系统解决,非意识流
模板(含示例)
保障系统进化
目标:类似故障不会再次发生
实施建议
-
针对故障暴露问题,从日常巡检、异常检测、故障处理三方面完善现有保障系统
-
此类故障预案演练,保证预案有效
定期故障集剖析
目标:量化分析全部case故障原因,针对性系统性改进
实施建议
-
周期:季度 or 月度
-
主R:架构师 or 技术leader
-
思路:
全部study原因量化分析,建议按开发、测试、运维角度拆分并细化
对主因制定改进方案,短期方案做到立竿见影,长期方案做到架构和开发流程改进 -
示例:
六、酒旅特有问题和具体例子
(业务安全,比如反爬。流量分级与运营)

浙公网安备 33010602011771号