This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
<audio id="audio" title="01SRE迷思无所不能的角色还是运维的升级" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/6c/b4/6c369871a455c580414561aca4f5c9b4.mp3"></audio>
你好,我是赵成。
作为这个课程的第一讲我先从实践的角度和你聊聊应该怎么理解SRE。
为什么要强调是实践的角度呢?
开篇词里我们就提到过有人认为SRE就是一个岗位而且是一个具备全栈能力的岗位只要有这么一个人他就能解决所有稳定性问题。这还只是一种理解而且这个理解多是站在管理者的角度。
也有人站在运维人员的角度认为做好SRE主要是做好监控做到快速发现问题、快速找到问题根因还有人站在平台的角度认为做好SRE要加强容量规划学习Google做到完全自动化的弹性伸缩甚至还有人认为SRE就是传统运维的升级版把运维自动化做好就行了。
你看其实不同的人站在不同的角度对SRE的理解就会天差地别但是好像又都有各自的道理。
所以我特别强调实践的角度我们不站队就看真实的落地情况。我总结了一下从实践角度看SRE的关键点就一个词**体系化**。**SRE是一套体系化的方法我们也只有用全局视角才能更透彻地理解它。**
好了下面我们就一起来看怎么理解SRE这个体系化工程。
## SRE我们应该怎么来理解它
我先给你分享一张图这是结合我自己团队的日常工作做出来的SRE稳定性保障规划图。<br>
<img src="https://static001.geekbang.org/resource/image/31/f6/31144fb00cf21005a8d0ae3dc02378f6.jpg" alt=""><br>
我们最初画这张图是为了提高故障处理效率将每个阶段可以做的事情填了进去并在实践中不断补充完善最终形成了我们探索SRE的框架图。你应该也发现了这里面很多事情都很常见比如容量评估、故障演练、服务降级、服务限流、异常熔断、监控告警等等。
这就是为什么我一直给你打气说SRE并不神秘。学习SRE我们可以有非常熟悉的抓手。但是我们不能停留在向Google或其他大厂学习具体的技术经验上而是更应该学习如何将这些技术有机地结合起来形成一套稳定性体系**让体系发挥出力量**,告别只发挥某项技术的能力。
同时结合这些具体的事情你应该明白这些工作并不是某个人、某个角色甚至是某个团队就可以单枪匹马完成的。比如这里的很多事情要依赖运维自动化像容量扩缩容必然会与运维团队有交集如果做得再弹性一些还需要与监控结合就要与监控团队有合作同时还可能依赖DevOps提供持续交付、配置变更以及灰度发布这些基础能力就要与开发和效能团队有交集。
这些能力之间的相互依赖,就决定了**从职能分工上SRE体系的建设绝不是单个岗位或单个部门就能独立完成的必然要求有高效的跨团队组织协作才可以**。
所以不要想着设定一个SRE岗位就能把稳定性的事情全部解决掉这明显不现实。你应该从体系的角度出发设置不同的职能岗位同时还要有让不同角色有效协作的机制。
从另一个角度来讲如果当前我们的稳定性建设还仅仅聚焦在某个或某些具体的技术点上每个角色和团队之间的工作相对还是独立、各自为战的那就说明SRE体系和组织的真正威力还没有发挥出来。
所以如果你已经是这些领域的实践者比如你是一个运维工程师或者是一位监控开发工程师又或者是一个DevOps开发工程师我建议你除了负责当前的事情外应该更多地关注一下SRE全局视图。这样会帮助你深入了解SRE岗位所需要的技术能力进而提升你的平台架构能力。
要知道如果严格遵循Google的要求SRE岗位对技术要求是非常高的。只有具备了全面的技术能力拥有了全局架构的思维你才会在SRE的道路上走得更远。
总结一下从实践角度来看SRE的力量不能通过一个岗位、一个或几个技术就发挥出来。SRE是一个体系化工程它需要协同多个部门、多项技术。
## 做好SRE的根本目的是什么
认识到SRE是个体系化的事儿还不够我们还可以“以终为始”看看SRE最后要达成什么样的目标以此来加深对它的理解。
SRE做了这么多的事情最后的目的是什么呢
这个答案很明显嘛,就是提升稳定性。但是怎样才算提升了稳定性呢?要回答这个问题,我们有必要来讨论下稳定性的衡量标准。
从业界稳定性通用的衡量标准看,有两个非常关键的指标:
- **MTBF**Mean Time Between Failure平均故障时间间隔。
- **MTTR**Mean Time To Repair 故障平均修复时间。
还来看前面的SRE稳定性保障规划图你会发现我们把整个软件运行周期按照这两个指标分成了两段。通俗地说MTBF指示了系统正常运行的阶段而MTTR则意味着系统故障状态的阶段。<br>
<img src="https://static001.geekbang.org/resource/image/b3/93/b3c54d78efe3a7616a5e0fc8c124df93.jpg" alt=""><br>
到了这里,我们也就明白了,如果想提升稳定性,就会有两个方向:**提升MTBF**,也就是减少故障发生次数,提升故障发生间隔时长;**降低MTTR**,故障不可避免,那就提升故障处理效率,减少故障影响时长。
你想,如果我们把故障发生时间的间隔变长,并将故障影响的时间减少,系统稳定性是不是自然就提升了呢?答案是显然的。
从SRE稳定性保障规划图中可以看出MTTR可以细分为4个指标MTTI、MTTK、MTTF和MTTV。我把它们的具体解释做了一张图你可以保存下来有时间就琢磨一下。这4个指标你要烂熟于心。<br>
<img src="https://static001.geekbang.org/resource/image/95/29/9542c5c234c8332f22a9f18b0707cf29.jpg" alt=""><br>
现在我们再来看SRE稳定性保障规划这张图你就会理解为什么要把所做的事情分组分块呈现。目的就是区分清楚**我们做的任何一件事情、开发的任何一套系统、引入的任何一个理念和方法论有且只有一个目标那就是“提升MTBF降低MTTR”**,也就是把故障发生时间的间隔变长,将故障影响的时间减少。
比如在Pre-MTBF阶段无故障阶段我们要做好架构设计提供限流、降级、熔断这些Design-for-Failure的服务治理手段以具备故障快速隔离的条件还可以考虑引入混沌工程这样的故障模拟机制在线上模拟故障提前发现问题。
在Post-MTBF阶段也就是上一故障刚结束开启新的MTBF阶段我们应该要做故障复盘总结经验找到不足落地改进措施等。
在MTTI阶段我们就需要依赖监控系统帮我们及时发现问题对于复杂度较高和体量非常大的系统要依赖AIOps的能力提升告警准确率做出精准的响应。
同时AIOps能力在大规模分布式系统中在MTTK阶段也非常关键因为我们在这个阶段需要确认根因至少是根因的范围。
你看,我们做了很多事情, 新的理念和方法出来后也特别愿意尝试,就是因为有明确的目标,所有工作的开展都是围绕这个核心目标而去的。
好了按照以终为始的思路SRE要实现的目标就是“提升MTBF、降低MTTR”从这个角度出发我们再次认识到一定要**把SRE作为一个体系化的工程来建设**,因为单纯在某些技术点上发力是没有多大意义的。
## 总结
今天我要分享的内容就到这里了。总结一下,你需要记住下面这两点。
第一我们需要从全局的角度去理解SRE。SRE一定是靠整个技术和组织体系发挥作用的单纯从某个技术点或环节出发都无法呈现出效果也就是说**SRE一定要从全局考虑体系一定要“配套”。**
第二SRE的目的本质上是减少故障时间增加系统正常运行时间也就是 **“减少故障提升MTBF同时提升故障处理效率降低MTTR”**。SRE要做的所有事儿都是为这两个目标服务的。
我想无论你是团队负责人、架构师,还是一线的技术专家,有了这样的全局视角后,就会知道接下来应该从何入手,以及如何与其他团队协作来构建这样的体系。
## 思考题
开篇词中我们提到过大家对SRE的困惑比如SRE和DevOps都是很好的方法论我应该怎么选到底哪个更适合我今天我们讲了SRE应该怎么理解我想对这个问题你应该有答案了。那就请你来说一说SRE和DevOps到底哪个更适合你它们有什么区别和相同点
请你在留言区说出自己的思考,也欢迎你把今天的内容分享给身边的朋友,和他一起讨论。
我们下节课见。

View File

@@ -0,0 +1,102 @@
<audio id="audio" title="02 | 系统可用性:没有故障,系统就一定是稳定的吗?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/38/d3/38a4aa516d29a6058be41aae51b456d3.mp3"></audio>
你好,我是赵成,欢迎回来。
我们先来复习一下上一讲的内容总结下来就是SRE是个体系化工程我们通过构建SRE这样一套体系来保证系统稳定性具体来说就是“提升MTBF降低MTTR”。有了这样一个激动人心的目标你是不是想着那咱还等什么赶快、立马就入手建设SRE体系吧
好想法我也很想咱就直接“撸起袖子加油干”。不过今天我们要先缓一缓在正式进入SRE落地细节之前我们得先讨论一下目前业界常用的“系统可用性Availability”这个概念也就是我们常常听到的“3个9”99.9%或99.95%、“4个9”99.99%或99.995%)。
为什么要先来讨论“系统可用性”这个大家已经很熟悉的概念呢?
一方面系统可用性和我们建设SRE的目标强相关SRE的稳定性目标其实就是尽量减少系统故障或异常运行状态的发生提升系统可用的运行时间占比。很明显这个可用时长就非常关键了。
另一方面系统可用性这个概念看似简单但我发现真的深入进去大家的理解其实有很多不一致的地方比如到底怎样才算是可用时长怎样算是不可用时长呢这个标准是怎么定义的除了从时间维度来衡量可用性还有其它的衡量方式吗“3个9”、“4个9”听起来都很好那具体来说我们的系统要达到“几个9”才算是稳定的呢
所以今天我们先慢下来花时间把上面这些问题都彻底搞清楚达成共识打好基础咱后面的SRE学习才能事半功倍。
## 衡量系统可用性的2种方式
那我就直接给答案了,目前业界有两种衡量系统可用性的方式,一个是时间维度,一个是请求维度,我们先来看这两个维度的计算公式。
- **时间维度Availability = Uptime / (Uptime + Downtime)**
- **请求维度Availability = Successful request / Total request**
这两个公式很简单,我们得深入进去,一一来看。
我们先来看时间维度的系统可用性。用一句话来概括:**时长维度,是从故障角度出发对系统稳定性进行评估**。
这类计算方式我们最常见,毕竟你的系统在一段时间里不出现故障,就说明它很稳定嘛!不过,在真实的使用场景中,怎么样才算是可用时长,什么情况下又是不可用时长,这个是怎么定义的呢?
细想一下这个问题,你会发现还真有点复杂,那我就举个发烧生病的例子来说明一下。
我们知道一个人如果发烧了体温一般会超过37.5度那如果这个人的体温正好达到这个温度是不是代表他一定是生病了呢依据生活经验我们知道不一定。为什么呢因为我们判断一个人是否发烧生病不是只看这一次、一时的体温还要看他体温是不是持续超过37.5度。
所以,这里就涉及到一个测量方法和判定方法的问题,包含三个要素:一个是**衡量指标**,比如体温就是衡量指标;第二个是**衡量目标**达到什么目标是正常达不到就是异常低于37.5度算正常超过37.5度就是异常但是单次测量不能说明问题我们可以多次测量比如6次中有至少4次低于37.5度才算正常转化成比例的话就是67%;第三个是**影响时长**比如持续超过12小时。
对应到系统上我们也会用一系列的标准和判定逻辑来说明系统是否正常。比如系统请求状态码为非5xx的比例也就是请求成功率低于95%已经连续超过10分钟这时就要算作故障那么10分钟就要纳入Downtime宕机时间如果达不到这个标准就不算作故障只是算作一般或偶然的异常问题。
这里同样有三个要素:**衡量指标**,系统请求状态码;**衡量目标**非5xx占比也就是成功率达到95%**影响时长**持续10分钟。
因此只有当问题达到一定影响程度才会算作故障这时才会计算不可用时长也就是上面公式中的Downtime。同时我们还要求一个周期内允许的Downtime或者说是系统的“生病时间”是有限的用这个有限时间来约束系统稳定性。
下面是我们常见的按时长维度统计的可用性对照表也就是我们前面提到的几个9<br>
<img src="https://static001.geekbang.org/resource/image/32/b6/32793cc21e9aa296c92a9ed59b0a41b6.jpg" alt=""><br>
讲到这里,针对时长维度的稳定性计算方式就比较清楚了,但是从这种计算方式中,你有没有看出一些问题呢?
我想你肯定看出来了,这里最显著的问题就是,稳定性只与故障发生挂钩。
我们来想一想这样做会带来哪些问题比如有一个系统因为网络抖动有短暂的几秒、十几秒或者几分钟异常但是后来系统自己恢复了业务并没有中断这时我们按照时长维度来判断这肯定不会算作系统故障。但是如果这种短暂的影响频度非常高一天来个5、6次持续一两周我们应该可以判定系统运行状况也是不正常的可能不是故障但肯定是不稳定了。
所以这种用时长维度来衡量系统稳定性的方式,其主要缺点就是粒度不够精细。这些小的异常问题和它们的影响,如果从更长的周期来看,也是有一定参考价值的。那怎样才能衡量得更精细些呢?
这就需要第二种衡量方式了,也就是从请求维度来衡量系统可用性。
用一句话来说,**请求维度,是从成功请求占比的角度出发,对系统的稳定性进行评估**。
假定我们的系统一天内有100,000次请求我们期望的成功率至少是95%如果有5001次请求失败了也就是成功率低于95%了,我们就认为系统运行状态是不正常的。
请求维度的系统可用性同样包含三个关键要素,第一个**衡量指标**,请求成功率;第二个**衡量目标**成功率达到95%才算系统运行正常;第三个是**统计周期**,比如一天、一周、一个月等等,我们是在一个统计周期内计算整体状况,而不是看单次的。
你看,这种方式对系统运行状况是否稳定监管得更为严格,不会漏掉任何一次问题的影响,因为它对系统整体运行的稳定性判定,不仅仅会通过单次的异常影响进行评估,还会累计叠加进行周期性的评估。
到这里,我们就总结出一条至关重要的经验了:**故障一定意味着不稳定,但是不稳定,并不意味着一定有故障发生**。
到这里,我们掌握了衡量系统可用性的两个维度、两种算法,它们都包含三个关键要素:衡量指标、衡量目标、影响时长/统计周期。这两种算法最后都会落脚到“几个9”上那系统到底定“几个9”才算是稳定的呢接下来我们就来回答这个问题。
## 设定系统稳定性目标要考虑的3个因素
这个问题其实并没有标准答案从我的经验来看到底定“几个9”主要取决于以下三个因素。
**第一个,成本因素。**
从理论上来说肯定是9越多稳定性越好但是相应付出的成本和代价也会更高。比如为了更高的可用性要有更多的冗余资源投入甚至要做主备、双活甚至是多活。如果一家公司的业务量和影响力都发展到一定程度那这个成本不管多高都是必须要付出的。但是肯定不是所有的公司都需要付出这么高的成本而是要先考虑ROI回报率。这时候就要看企业自身对成本压力的承担情况了。
**第二个,业务容忍度。**
稳定性怎么设定很大程度上还要取决于业务上的容忍度。对于核心业务或核心应用比如电商的交易和支付系统我们当然是希望成功率越高越好一般对系统稳定性要求是“3个9”或“4个9”。因为这些系统一旦出问题就会直接影响整个网站和公司的收益这些都是钱所以对稳定性要求必然就会提高。
但是对于非核心业务或应用比如商品评论商品评分等或许“2个9”也能容忍。因为短时间的评论看不到并不会对业务收入和用户体验造成太大的影响。
**第三个,系统当前的稳定性状况。**
结合系统的实际情况,**定一个合理的标准比定一个更高的标准会更重要**。这个合理的值应该怎么来定呢?
我个人的建议是从系统现状入手比如如果系统可用性是低于99%的那首先第一步是不是可以做到99%然后再争取做到99.5%再到99.9%,一步一步朝着更高的标准迈进。同时,这样做也会更容易落地,因为你如果定一个太高的目标,又始终达不成,反而会打击到团队的自信心和积极性。
结合上面这三个因素对于到底应该定“几个9”这个问题你应该有了一个更清晰的认识了。
## 总结
好了到这里今天我们要讨论的系统可用性就讲完了。关于系统可用性业界有两种计算方式一种是时长维度另一种是请求维度这两种方式各有优劣。在SRE的实践中应该选择哪一个呢很明显SRE会更多采用请求维度的统计方式因为**SRE关注的稳定性是系统的整体运行状态而不仅仅只关注故障状态下的稳定性在系统运行过程中的任何异常都会被纳入稳定性的评估范畴中。**
这个知识点要拿一整节课来讲是因为接下来我们就要讨论SRE的稳定性指标和目标了理解了今天的内容你才能更好地理解SRE体系中的指标SLI和目标SLO。今天我先把SLI和SLO这两个概念抛出来如果你觉得有点陌生没有关系准备好下节课和我一起掌握它们。
## 思考题
对于系统可用性的描述,今天我们仅用了“状态码”这一个指标来示例,但是在实际情况下,我们还会有其它多个指标来同时标识一个系统的稳定性,你能想到还有哪些指标?欢迎你在留言区写下自己的思考。
考虑这些指标的时候,不妨想想你是怎么选择的,你的判断标准是什么?这些也将是我们下节课程的重点内容。
如果今天的内容对你有帮助,也欢迎你分享给身边的朋友,和他一起精进。
我是赵成,我们下节课见。

View File

@@ -0,0 +1,160 @@
<audio id="audio" title="03 | SRE切入点选择SLI设定SLO" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/2e/b1/2e8280888c9d2978da98c71cc4956eb1.mp3"></audio>
你好,我是赵成,欢迎回来。
还是先来复习下上节课讲的“系统可用性”的两种计算方式一种是从故障角度出发以时长维度对系统进行稳定性评估另一种是从成功请求占比角度出发以请求维度对系统进行稳定性评估。同时我们还讲到在SRE实践中通常会选择第二种也就是根据成功请求的比例来衡量稳定性
**Availability = Successful request / Total request**
SRE强调的稳定性一般不是看单次请求的成功与否而是看整体情况所以我们会把成功请求的占比设定为一个可以接受的目标也就是我们常说的“3个9”或“4个9”这样的可量化的数字。
那么这个“确定成功请求条件设定达成占比目标”的过程在SRE中就是**设定稳定性衡量标准的SLI和SLO的过程**。
具体来看下这两个概念。SLIService Level Indicator服务等级指标其实就是我们选择哪些指标来衡量我们的稳定性。而SLOService Level Objective服务等级目标指的就是我们设定的稳定性目标比如“几个9”这样的目标。
SLI和SLO这两个概念你一定要牢牢记住接下来我们会反复讲到它们因为落地SRE的第一步其实就是“**选择合适的SLI设定对应的SLO**”。
那我们就正式开始今天的内容。我会带你彻底理解SLI和SLO这两个概念并掌握识别SLI、设定SLO的具体方法。
### SLI和SLO到底是啥
SLI和SLO这两个概念比较有意思看字面意思好像就已经很明白了但是呢仔细一想你会发现它们很抽象。SLI和SLO指的到底是啥呢
接下来我给你讲一个具体的例子,讲完后,你肯定就能理解了。
我们以电商交易系统中的一个核心应用“购物车”为例给它取名叫做trade_cart。trade_cart是以请求维度来衡量稳定性的也就是说单次请求如果返回的是非5xx的状态码我们认为该次请求是成功的如果返回的是5xx状态码如我们常见的502或503我们就判断这次请求是失败的。
但是这个状态码只能标识单次请求的场景。我们之前讲过单次的异常与否并不能代表这个应用是否稳定所以我们就要看在一个周期内所有调用次数的成功率是多少以此来确定它是否稳定。比如我们给这个“状态码返回为非5xx的比例”设定一个目标如果大于等于99.95%,我们就认为这个应用是稳定的。
在SRE实践中我们用SLI和SLO来描述。“状态码为非5xx的比例”就是SLI“大于等于99.95%”就是SLO。说得更直接一点SLO是SLI要达成的目标。
通过这个例子你现在是不是已经理解了这两个概念呢。SLI就是我们要监控的指标SLO就是这个指标对应的目标。
好,那接下来我们要解决的问题就很具体了。我们应该选择哪些指标来监控系统的稳定性?指标选好后,对应地怎么定它的目标呢?下面咱们就一一来探索。
#### 系统运行状态指标那么多哪些适合SLI
我们先来讨论怎么选择SLI。要回答怎么选择这个问题我们得先来看看都有哪些可供选择的指标。
在下面这张图中,我列举了系统中常见的监控指标。<br>
<img src="https://static001.geekbang.org/resource/image/e8/9c/e8a49d7fbfb8df42db84efe44f48f59c.jpg" alt=""><br>
这些指标是不是都很熟悉?那该怎么选呢?好像每一个指标都很重要啊!
确实,这些指标都很重要。我们可以通过问自己两个问题来选择。
第一个问题:**我要衡量谁的稳定性?** 也就是先找到稳定性的主体。主体确定后,我们继续问第二问题:**这个指标能够标识这个实例是否稳定吗?** 一般来说这两个问题解决了SLI指标也就确认了。
从我的经验来看,给指标分层非常关键。就像上图那样分层后,再看稳定性主体是属于哪一层的,就可以在这一层里选择适合的指标。但是,你要注意,即便都是应用层的,针对具体的主体,这一层的指标也不是每一个都适合。
根据这几年的实践经验我总结了选择SLI指标的两大原则。
**原则一:选择能够标识一个主体是否稳定的指标,如果不是这个主体本身的指标,或者不能标识主体稳定性的,就要排除在外。**
**原则二:针对电商这类有用户界面的业务系统,优先选择与用户体验强相关或用户可以明显感知的指标。**
还拿我们上面trade_cart的例子来说主体确定了就是trade_cart应用层面的请求返回状态码和时延就是很好的指标再来检查下它们能否标识的trade_cart稳定性毫无疑问这两个指标都可以那么请求返回状态码和时延就可以作为trade_cart稳定性的SLI指标。
我们换一个指标CPU的使用率这个指标适合吗根据我们刚才说的原则既然我们关注的是trade_cart的运行状况而CPU是系统层的指标所以在选择应用层SLI的指标时自然会把CPU排除掉。
你可能会说,这样是不是太武断了呀?
我们简单来分析下。假设CPU使用率达到了95%但是只要CPU处理能力足够状态码成功率可能还是保持在4个9时延还是在80ms以内用户体验没有受到影响。另外一种情况假设CPU使用率只有10%但是可能因为网络超时或中断导致大量的请求失败甚至是时延飙升购物车这个应用的运行状态也不一定是正常的。所以结论就是CPU使用率不管是10%还是95%都不能直接反映trade_cart运行是正常还是异常不适合作为trade_cart这样的应用运行稳定性的SLI指标。
讲到这里你可能会问哎呀你说的这两个原则我理解了分层也大概能做到但是我还是需要做很多详细的分析才能选择出SLI指标有没有什么更便捷、更快速的方法来帮助我选择啊
不要着急还真有这样一套方法。怎么选SLI我们可以直接借鉴Google的方法VALET。
## 快速识别SLI指标的方法VALET
VALET是5个单词的首字母分别是Volume、Availability、Latency、Error和Ticket。这5个单词就是我们选择SLI指标的5个维度。我们还是结合trade_cart这个例子一起看一下每个维度具体是什么。
**Volume-容量**
Volume容量是指服务承诺的最大容量是多少。比如一个应用集群的QPS、TPS、会话数以及连接数等等如果我们对日常设定一个目标就是日常的容量SLO对双11这样的大促设定一个目标就是大促SLO。对于数据平台我们要看它的吞吐能力比如每小时能处理的记录数或任务数。
**Availablity-可用性**
Availablity可用性代表服务是否正常。比如我们前面介绍到的请求调用的非5xx状态码成功率就可以归于可用性。对于数据平台我们就看任务的执行成功情况这个也可以根据不同的任务执行状态码来归类。
**Latency-时延**
Latency时延是说响应是否足够快。这是一个会直接影响用户访问体验的指标。对于任务类的作业我们会看每个任务是否在规定时间内完成了。
讲到这里我要延伸下因为通常对于时延这个指标我们不会直接做所有请求时延的平均因为整个时延的分布也符合正态分布所以通常会以类似“90%请求的时延 &lt;= 80ms或者95%请求的时延 &lt;=120ms ”这样的方式来设定时延SLO熟悉数理统计的同学应该知道这个90%或95%我们称之为置信区间。
因为不排除很多请求从业务逻辑层面是不成功的这时业务逻辑的处理时长就会非常短可能10ms或者出现404这样的状态码可能就1ms。从可用性来讲这些请求也算成功但是这样的请求会拉低整个均值。
同时也会出现另一种极端情况就是某几次请求因为各种原因导致时延高了到了500ms但是因为次数所占比例较低数据被平均掉了单纯从平均值来看是没有异常的。但是从实际情况看有少部分用户的体验其实已经非常糟糕了。所以为了识别出这种情况我们就要设定不同的置信区间来找出这样的用户占比有针对性地解决。
**Errors-错误率**
错误率有多少这里除了5xx之外我们还可以把4xx列进来因为前面我们的服务可用性不错但是从业务和体验角度4xx太多用户也是不能接受的。
或者可以增加一些自定义的状态码,看哪些状态是对业务有损的,比如某些热门商品总是缺货,用户登录验证码总是输入错误,这些虽不是系统错误,但从业务角度来看,对用户的体验影响还是比较大的。
**Tickets-人工介入**
是否需要人工介入?如果一项工作或任务需要人工介入,那说明一定是低效或有问题的。举一个我们常见的场景,数据任务跑失败了,但是无法自动恢复,这时就要人工介入恢复;或者超时了,也需要人工介入,来中断任务、重启拉起来跑等等。
Tickets的SLO可以想象成它的中文含义门票。一个周期内门票数量是固定的比如每月20张每次人工介入就消耗一张如果消耗完了还需要人工介入那就是不达标了。
这里我给出一个Google提供的针对类似于我们trade_cart的一个应用服务基于VALET设计出来的SLO的Dashboard样例结合上面我们介绍的部分就一目了然了。<br>
<img src="https://static001.geekbang.org/resource/image/fa/f8/fafcdd765f8a58a42fbc75bfca4fd7f8.png" alt="" title="VALET示例图"><br>
VALET我们就讲完了怎么选SLI指标你是不是一下子就清楚了。可以说这是一个我们可以直接复用的工具。上面Google的这张SLO样例图建议你多看几遍看到时候对比思考下自己系统的情况。
## 如何通过SLO计算可用性
到这里我们已经能够根据自己想要保障稳定性的主体来选择合适的SLI指标了也知道SLO就是对应SLI要实现的目标比如“几个9”。
但是,我们前面讲到了系统可用性:
**Availability = Successful request / Total request**
然后又深入到了提炼具体的SLI以及设定对应的SLO那这两者之间是什么关系呢也就是通过SLO应该怎么去计算我们的系统可用性的呢这就涉及到系统整体可用性的两种计算方式。
**第一种,直接根据成功的定义来计算**<br>
也就是我们前面定义一个请求的返回状态码必须是非5xx才算成功同时时延还要低于80ms同时满足这两个条件我们才算是成功的也就是纳入上述公式中Successful request的统计中用公式来表示
**Successful = 状态码非5xx &amp; (时延 &lt;= 80ms**
如果还有其它条件,直接在后面增加做综合判定。
但是这种计算方式存在的问题就是对单次请求的成功与否的判定太过死板容易错杀误判。比如我们前面讲对于时延我们一般会设定置信区间比如90%时延小于等于200ms这样的场景用这种方式就很难体现出来。而且对于状态码成功率和时延成功率的容忍度通常也是也不一样的通过这种方式就不够准确。所以我们就会采取第二种方式。
**第二种方式SLO方式计算**
我们前面讲时延时讲过以下几个SLO这时我们设定稳定性的时候就需要把公式计算方式灵活调整定义一下了。
- SLO199.95% 状态码成功率
- SLO290% Latency &lt;= 80ms
- SLO399% Latency &lt;= 200ms
直接用公式表示:
**Availability = SLO1 &amp; SLO2 &amp; SLO3**
只有当这个三个SLO同时达标时整个系统的稳定性才算达标有一个不达标就不算达标这样就可以很好地将SLO设定的合理性与最终可用性结合了起来。所以通常在SRE实践中我们通常会采用这种设定方式。
如果是这样第一种方式是不是就没有用途了呢当然不是。第一种计算方式也会有它特有的应用场景它通常会被利用在第三方提供的服务承诺中也就是SLA Service Level Agreement。因为对于第三方提供商来说比如云厂商它们要面对的客户群体是非常大的所以很难跟每一家客户都去制定像SLO这么细粒度稳定性目标而且每家客户对稳定性的要求和感知也不同就没法统一。
这种情况下反而是第一种计算方式是相对简单直接的但是这样也决定了SLA的承诺相比SLO肯定也相对比较宽松因为SLA是商业服务承诺如果达不成是要进行赔偿的。关于SLA最直接的参考资料就是各个公有云厂商在官网公开的信息资料你可以找到这些资料作为自己的一个补充学习。
## 总结
讲到这里怎么选择SLI指标、如何制定SLO目标我们就介绍完了。你需要掌握下面三个重点。
1. 对系统相关指标要分层识别出我们要保障稳定性的主体系统、业务或应用是什么然后基于这个主体来选择合适的SLI指标。
1. 不是所有的指标都是适合做SLI指标它一定要能够直接体现和反映主体的稳定性状态。可以优先选择用户或使用者能感受到的体验类指标比如时延、可用性、错误率等。
1. 掌握VALET方法快速选择SLI指标。
## 思考题
最后,给你留一个思考题。
下面我给出一个Google的SLI和SLO设定标准示例内容很直观需要你认真研究一下这个文档结合今天我们所讲的内容请你尝试按照Google提供的规范格式制定一个自己所负责系统的SLO。
Google的SLI和SLO设定模板链接[https://landing.google.com/sre/workbook/chapters/slo-document](https://landing.google.com/sre/workbook/chapters/slo-document)
另外,对今天的内容如果你还有什么疑惑,都可以在留言区提问,也欢迎你把今天的内容分享给身边的朋友,和他一起学习讨论。
我是赵成,我们下节课见。

View File

@@ -0,0 +1,162 @@
<audio id="audio" title="04 | 错误预算:达成稳定性目标的共识机制" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/78/b0/7851a45ecfcc73a8c8b4c0deaba4a5b0.mp3"></audio>
你好,我是赵成,欢迎回来。
上一讲是我们引入SRE的关键我们掌握了选择SLI指标和设定SLO目标的方法。你可以先回顾一下内容看看是不是能回答这三个问题选择SLI的两大原则是什么VALET法则是什么怎么来计算SLO如果答案都很清晰那么恭喜你你攻克了SRE的一个关键知识点如果有点模糊那就回去复习一下咱不求快但求扎实。
今天我们就顺着SLO这条线继续深入一起来看有了SLO之后围绕着它我们可以做哪些事情或者说我们具体应该怎么来应用SLO呢还有SLO设定后是合理还是不合理我们应该用什么样的方法来评估呢如果设定得不合理我们又应该怎么来调整呢
带着这些问题,开始我们今天的学习。
## 落地SLO先转化为Error Budget
SLO是目标定目标总是一件激动人心的事但是目标定了之后这个目标怎么能指导我们的具体工作呢有时候就没那么一目了然了。
这么说有点抽象我举个生活中的例子。你通过好几轮考试拿到了驾照现在你可以开车上路了。交管局的目标就是你要遵守交规安全驾驶。这个目标咋实现呢我们都知道了就是驾照记分制。你的驾照在1年的这个周期里总共有12分扣完了驾照失效这样你就会关注自己还有几分特别注意交规。用这个方式就把你要趋近100%遵守交规的目标转变为你一年只有12分可扣一个大目标就有了很具体的落地形式。
那同样SLO目标定好了很具体但实施起来不直观那我们是不是也可以反过来看制定出一个允许犯错的次数标准这样我们就监控这些错误就好了。
没错SRE还真是这么做的这个概念叫做Error Budget翻译过来就是错误预算。
错误预算其实和驾照记分制是一样的,**最大的作用就是“提示你还有多少次犯错的机会”**,并且,错误预算的警示效果比看成功率这种统计数据更直观,感官冲击力更强。
那在SLO中错误预算是怎么得出的呢其实计算方式一点都不复杂简单讲就是**通过SLO反向推导出来**的。下面我举个例子,你马上就可以理解了。
我们还是以trade_cart购物车这个应用为例SLO目标就是我们上节课定过的。假设在4周的时间这个应用所有的请求次数是4,653,680按照给出的SLO反向推导就可以得到容许的错误次数这就是错误预算。<br>
<img src="https://static001.geekbang.org/resource/image/7b/23/7b797671f850c1cfe6d82c53d0e37c23.jpg" alt=""><br>
你看,错误预算的计算很简单,起到的警示效果又更强烈,所以**在SLO落地实践时我们通常就把SLO转化为错误预算以此来推进稳定性目标达成**。
那在实际场景下我们应该怎么应用错误预算呢下面我给你介绍常见的4种应用方式。
## 如何应用Error Budget
#### 1.稳定性燃尽图
第一种是稳定性燃尽图。
当我们制定好错误预算后就代表了要严格遵守它。如果在一个周期内比如4个自然周错误预算被消耗完了尽管整个过程中没有出现达到故障标准的问题这个周期的稳定性要求其实也是不达标的。
所以我们需要把错误预算尽可能直观地表现出来随时可以看到它的消耗情况。当你和团队成员能够时刻看到还有多少犯错的机会时对生产系统的敬畏心理也会大大增强。而且当错误预算消耗到一定比例如80%或90%时,就要开始预警,控制各种变更,或者投入精力去解决影响稳定性的问题。
那怎么制作稳定性燃尽图呢?
这里可以参考Google给出的一个错误预算的燃尽图这个从技术上通过你日常使用的监控平台配置一个Metric就可以实现并不复杂。<br>
<img src="https://static001.geekbang.org/resource/image/5d/3c/5d52eb6b0af3912d8ec39f781e2d643c.jpg" alt="" title="错误预算的燃尽图"><br>
在应用错误预算的时候你要考虑设定一个合理的周期比如1天、1周或1个月。
1天或1周周期相对较短我们通常的建议是4个自然周这个周期设定更合理这也是谷歌给出的建议。为什么选4个自然周而不是1个自然月呢主要是因为自然月通常会导致跨周的情况出现相比于4个自然周在统计上就要考虑额外的边界问题。
同时在考虑定错误预算的时候还要考虑到部分特殊场景这个要根据业务特点来定比如电商会有双11大促活动有些产品还要考虑春晚互动活动和抢红包活动甚至有些社交类产品还要考虑应对突发新闻导致的访问量激增问题等等这些场景必然因为访问量太大而采取很多限流降级的策略导致更多的请求失败。
如果这些活动或事件是发生在某个考核周期内,这时要考虑放大错误预算的值,特别是瞬时的错误或失败,应该要有更大的容忍度,简单来讲就是,特殊情况特殊处理,当然最重要的,也要做好特殊保障和应对工作。
#### 2.故障定级
第二种是把错误预算应用在故障定级中。我们判定一个问题是不是故障,或者评估问题影响程度到底有多大,除了看影响时长外,还有一个更具操作性的方法,那就是按照该问题消耗的错误预算比例来评判。
我在《赵成的运维体系管理课》[第28讲](https://time.geekbang.org/column/article/4628)中分享过蘑菇街的故障定级思路,我们将故障等级设置为 P0~P4 这么 5 个级别P0 为最高P4 为最低。
还是以trade_cart购物车为例结合P0P4的故障等级设置一起来看怎么应用错误预算。
trade_cart请求成功率SLO对应的错误预算是25,000次如果一个问题产生的错误请求数超过了5000次也就是错误预算一下就被消耗掉20%以上这时我们可以把这次故障定为P2级。以此类推如果消耗30%以上我们定为P1级消耗50%以上定为P0级等等。
<img src="https://static001.geekbang.org/resource/image/88/94/88f7d168211dd600193359903a526594.jpg" alt="">
当然,我这里是举例,在真正实际工作中,这个具体数值可以根据实际业务情况和容忍度来制定。
可以看到,通过错误预算来定义故障等级就可以做到量化,而一旦可以被量化,就意味着可以标准化,有了标准,我们就可以进而推进达成共识。
#### 3.稳定性共识机制
第三种是用错误预算来确定稳定性共识机制。
前面我们用驾照记分来类比错误预算。现在想想当你发现自己只剩下1分的时候你会怎么办开车肯定会非常小心比如说慢速行驶严格遵守交通规则甚至是不开车这些行为都是围绕“驾照记分只剩1分”这个结果来做的。
同样在我们系统稳定性保障过程中我们也会根据剩余预算的情况来制定相应的行动措施来避免我们的稳定性目标也就是SLO达不成。
那么,当错误预算处于不同状态时,我们一般都会采取哪些常见措施呢?这里我给你介绍两个指导原则。
**第一,剩余预算充足或未消耗完之前,对问题的发生要有容忍度。**
比如4周的一个周期内如果错误预算没有被消耗完我们强调即使出现一些问题甚至是故障我们是要容忍的。
比如,网络抖动或设备瞬时切换导致了极短暂的系统不稳定,但是有极少一部分客户反馈了,也可能领导或业务使用时遇到了,结果技术同学就被投诉系统或业务不稳定,然后就要放下手头的工作去排查问题,后续还要花大量的时间去复盘总结和汇报等等。
这个场景发生的原因就是我在开篇词中提到的,每个角色对问题和故障的定义以及理解是不一致的,所以出现问题的时候,任何人、任何角色都可以凭个人感觉对问题影响程度进行评判。
遇到这种情况,你一般是怎么应对的?不知道该听谁的?还是先听一个,一头扎进去排查问题?
现在你有了SLO和错误预算的判断标准就有了明确的应对思路。如果预算充足且单次问题并没有造成大量损耗那么这次问题就不应该被投诉也不用以高优先级响应它应该得到容忍的。
**第二剩余预算消耗过快或即将消耗完之前SRE有权中止和拒绝任何线上变更。**
为什么这么说呢因为此时的情况已经说明系统稳定出现了很大问题不能再让它“带病工作”。同样这时的业务开发团队也有权拒绝新的需求他们首要的事情应该是跟SRE一起解决影响稳定性的问题直至问题解决且等到下一个周期有了新的错误预算后再恢复正常变更节奏。
从上面这两个原则中我们可以看到,跟驾照扣分触发的行动不同,保障稳定性的行动不是单独某一方就可以完成的,它需要多方共同认可并愿意配合才能真正执行到位。
所以你在制定SLO和错误预算策略的过程中要有一个很重要的动作就是确保与运营、产品和开发达成一致各方要认可这个策略并且当策略被触发时大家也会严格遵守。
可以看到,这里涉及到跨团队沟通共识机制。**从推行的角度来讲建立稳定性共识机制一定是Top-Down也就是自上而下至少要从技术VP或CTO的角度去推行**而且当有意见不一致的情况出现时还要逐步上升直至CTO角度来做决策。关于这一点你需要特别注意一定要**自上而下推进周边团队或利益方达成共识。**
#### 4.基于错误预算的告警
第四种是把错误预算应用在告警中。
日常工作中作为一线的工程师你肯定要接收大量的告警短信但是这些告警里面很大一部分都是没有实际意义的。为什么这么说呢因为它们没有行动指导意义比如CPU使用率80%、成功率低于95%、时延超过80ms等等这样的告警只是告诉我们有问题、有异常但是否需要高优先级马上处理还是说可以先放一放、过一会再处理呢你可能并没有办法判断。
这样的告警,接收的次数多了,就会变成“狼来了”,你自己变得警惕性不高,当故障真的发生时,你也没法快速响应。
那我们应当如何做告警收敛呢?从我的经验看,有两个解决办法。
- 第一个,相同相似告警,合并后发送,比如同一应用集群内同一时间内,同一异常告警,就先合并,对外只发送一条,这种比较简单直接。
- 第二个基于错误预算来做告警也就是说我们只关注对稳定性造成影响的告警比如我们前面提到的当单次问题消耗的错误预算达到20%或30%等某一阈值时,就意味着问题非常严重了,这种告警信息一旦收到,就要马上做出响应。这样告警数量不多,既达到了收敛效果,又非常精准。
基于错误预算的告警就会涉及到AIOps相关的领域我就不再展开讲了。这里我分享一个链接[谷歌基于SLO和错误预算的几种告警算法](https://landing.google.com/sre/workbook/chapters/alerting-on-slos/),你可以学习下里面用到的方法。
讲到这里基于错误预算的4个应用场景就介绍完了我们小结一下。我们将SLO反向推导出了错误预算为了让错误预算的警示效果更显著我们可以利用燃尽图的方式呈现出来同时还可以根据每次问题消耗的错误预算比例来制定故障等级这样就做到了对故障的量化管理有了量化数据在向周边团队和上级领导沟通时也会显得有理有据最后基于错误预算我们还可以做到告警收敛让告警更准确更具备行动指导价值。
既然我们制定了SLO推导出了错误预算也做好了相应的策略那我们制定的这些目标和规则是否有效果呢我们应该怎么来评价它们的有效性又应该怎么进一步迭代优化呢
下面我们就一起来看一下如何衡量SLO的有效性。
## 如何衡量SLO的有效性
衡量SLO及错误预算策略是否有效其实就是看实际运行后是否真的能达到我们的期望。我们可以从下面三个关键维度来看。
- **SLO达成情况**。我们用达成Met或未达成Missed来表示。
- **“人肉”投入程度**。英文表示为Toil这里用形象一点的“人肉”投入作为它的译意泛指需要大量人工投入、重复、繁琐且没有太多价值的事情。我们用投入程度高High和低Low来表示。
- **用户满意度**。英文就是Customer Satisfaction可以理解为用户感受和体验如何。这个信息可以通过真实和虚拟渠道获得。真实渠道如客服投诉、客户访谈和舆情监控获取虚拟渠道如真机模拟拨测。我们用满意度高High和低Low来表示。
总共3个维度每个维度有2种情况组合起来就是8种情况我们直接引用Google给出的图表和建议。<br>
<img src="https://static001.geekbang.org/resource/image/0a/25/0a2f80c62ca55c574aa7ebfc1fb76725.jpg" alt=""><br>
针对这8种情况我们分别给出对应策略。总结一下应对方式可以分为3类。
**第一类收紧SLO**
这个时候就是目标定得太低了比如SLO达成Met但是用户不满意Low。会有什么后果呢要么投诉多要么到处吐槽。这就表示我们的SLO设定得太容易达成没有反馈真实的运行状况。
**第二类放宽SLO**
与第一类相反目标定太高总是达不成Missed但用户反馈却很不错High这种就会造成错误预算提前消耗完导致很多变更暂停产品延期甚至会做一些无谓的优化这时就可以适当松松绑。
**第三类,保持现状,对有问题的维度采取有针对性的优化措施**
比如表格第一行是我们期望的最理想状态SLO能达成人肉投入又低客户满意度又很高也没有特别的优化空间这时我们就可以增加发布和变更次数更大程度地释放生产力。
你可以参考这个样例从SLO达成情况、“人肉”投入情况以及用户实际满意度三个维度来衡量自己业务和系统的SLO有效性该收紧SLO就要提高稳定性要求但是也不能设定太过超出能力范围的目标始终达不成SLO也就没有意义了。当然在SLO可以达成的情况下我们还是希望提升我们的用户价值交付效率围绕着这个终极目标不断优化自己的SLO和错误预算策略。
## 总结
今天的内容就讲解完了,我们重点讨论了错误预算,这里我要再强调几个关键点。
1. 错误预算是通过SLO推导出来的为了达成SLO就要尽量减少对它的消耗。
1. 错误预算的警示效果更显著所以我们通常会围绕它来开展稳定性保障工作。落地错误预算可以遵循一些基本原则比如要对系统故障或问题有容忍度在预算消耗过快或消耗殆尽之前SRE有权踩踩“刹车”减少或拒绝线上变更等等这些策略要自上而下达成共识。
1. SLO和错误预算是否合理基于它们的策略是否有效我们可以通过SLO达成情况、人肉投入程度和用户满意度三个维度进行评估进而调整和优化它们。
## 思考题
最后,给你留一个思考题。
今天我们讨论了把错误预算应用在故障定级中。其中,故障定级有时是一个特别让人头疼的事情,也需要跟周边团队达成一致。你能不能分享一下,在你的团队中,是用什么样的标准来制定故障等级的?
期待你在留言区说出自己的思考,也欢迎你把今天的内容分享给身边的朋友,和他一起讨论。我们下节课见。

View File

@@ -0,0 +1,123 @@
<audio id="audio" title="05 | 案例落地SLO时还需要考虑哪些因素" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/fc/7d/fcdc5aa7c3e312886f9cd723fdaa387d.mp3"></audio>
你好,我是赵成,欢迎回来。
前面几节课我们按照层层递进的思路从可用性讲到SLI和SLO再到SLO所对应的Error Budget策略。掌握了这些内容也就为我们建设SRE体系打下了一个稳固的基础。
今天我用一个电商系统的案例带着你从头开始一步一步系统性地设定SLO一方面巩固我们前面所学的内容另一方面继续和你分享一些我在实践中总结的注意事项。
## 案例背景
我先来给你介绍下电商系统案例的基础情况,框定下我们今天要讨论的内容范围。
一般来说,电商系统一定有一个或几个核心服务,比如要给用户提供商品选择、搜索和购买的服务等。但我们知道,大部分用户并不是上来就购买,而是会有一个访问的过程,他们会先登录,再搜索,然后访问一个或多个商品详情介绍,决定是放到购物车候选,还是选择物流地址后直接下单,最后支付购买。
这条从登录到购买的链路,我们一般称之为系统的**核心链路**Critical Path系统或网站就是依靠这样一条访问链路为用户提供了购买商品的服务能力。
至于电商系统的其它页面或能力,比如网站政策、新手指导、开店指南等等,这些对用户购买服务不会造成太大影响的,相对于核心链路来说,它的重要性就相对低一些。
我们要给电商系统设定SLO大的原则就是**先设定核心链路的SLO然后根据核心链路进行SLO的分解**。接下来,我们就一步步拆解动作,看看怎么实现这个目标。
## 核心链路:确定核心应用与强弱依赖关系
要确定核心链路的SLO我们得先找到核心链路。怎么实现呢
我们可以先通过全链路跟踪这样的技术手段找出所有相关应用,也就是呈现出调用关系的拓扑图,下面我给了一张图,这个图你应该并不陌生,这是亚马逊电商分布式系统的真实调用关系拓扑图。之所以这么复杂,是因为即使是单条路径,它实际覆盖的应用也是很多的,特别是对于大型的分布式业务系统,可能会有几十甚至上百个路径,这些应用之间的依赖关系也特别复杂。
<img src="https://static001.geekbang.org/resource/image/9d/cd/9d8c091d54bafb0c3d3f78b8637a63cd.png" alt="" title="亚马逊电商分布式系统调用关系拓扑图"><br>
面对这样复杂的应用关系,是不是感觉无从下手?那就继续来做精简,也就是**区分哪些是核心应用,哪些是非核心应用**。这是要根据业务场景和特点来决定的,基本上需要对每个应用逐个进行分析和讨论。这个过程可能要投入大量的人工来才能完成,但这个是基础,虽然繁琐且费时费力,也一定要做。
这里我简单举个例子说明。
比如用户访问商品详情的时候,会同时展现商品评价信息,但是这些信息不展现,对于用户选择商品也不会造成非常大影响,特别是在双十一大促这样的场景中,用户在这个时刻的目的很明确,就是购买商品,并不是看评价。所以类似商品评价的应用是可以降级的,或者短时间不提供服务。那这种不影响核心业务的应用就可以归为非核心应用。
相反的像商品SKU或优惠券这样的应用直接决定了用户最终的购买金额这种应用在任何时刻都要保持高可用。那这种必须是高可用的应用就是核心应用。
就这样,我们需要投入一些精力一一来看,确定哪些是核心应用,哪些是非核心应用。梳理完成后,针对电商系统,我们大概可以得到一个类似下图的简化拓扑关系(当然了,这里仍然是示例,相对简化,主要是保证效果上一目了然)。<br>
<img src="https://static001.geekbang.org/resource/image/e1/94/e1b5677cb26b0fb02ee29b1fd3153c94.jpg" alt=""><br>
这张图就呈现出一条典型的电商交易的关键路径,其中绿色部分为核心应用,蓝色部分为非核心应用。
这个时候,我们又要进行关键的一步了,就是确认强弱依赖。
**核心应用之间的依赖关系,我们称之为强依赖,而其它应用之间的依赖关系,我们称之为弱依赖**,这里就包含两种关系,一种是核心应用与非核心应用之间的依赖,另一种是非核心应用之间的依赖。
好了至此我们就确定了这个电商系统的核心应用和强弱依赖关系也就是找到了这个系统的核心链路。那我们就可以设定这条核心链路的SLO了并基于此设定其他的SLO。这时应该遵循哪些原则呢
## 设定SLO有哪些原则
针对核心和非核心应用以及强弱依赖关系我们在设定SLO时的要求也是不同的具体来说可以采取下面4个原则。
**第一核心应用的SLO要更严格非核心应用可以放宽。** 这么做就是为了确保SRE的精力能够更多地关注在核心业务上。
**第二强依赖之间的核心应用SLO要一致。** 比如下单的Buy应用要依赖Coupon这个促销应用我们要求下单成功率的SLO要99.95%如果Coupon只有99.9%那很显然下单成功率是达不成目标的所以我们就会要求Coupon的成功率SLO也要达到99.95% 。
**第三,弱依赖中,核心应用对非核心的依赖,要有降级、熔断和限流等服务治理手段。** 这样做是为了避免由非核心应用的异常而导致核心应用SLO不达标。
**第四Error Budget策略核心应用的错误预算要共享就是如果某个核心应用错误预算消耗完SLO没有达成那整条链路原则上是要全部暂停操作的**,因为对于用户来说,他不会判断是因为哪个应用有问题,导致的体验或感受不好。所以,单个应用的错误预算消耗完,都要停止变更,等问题完全解决再恢复变更。当然,也可以根据实际情况适当宽松,如果某个核心应用自身预算充足,且变更不影响核心链路功能,也可以按照自己的节奏继续做变更。这一点,你可以根据业务情况自行判断。
## 如何验证核心链路的SLO
梳理出系统的核心链路并设定好SLO后我们需要一些手段来进行验证。这里我给你介绍两种手段一种是容量压测另一种就是Chaos Engineering也就是混沌工程。
#### 容量压测
我们先来看容量压测。容量压测的主要作用就是看SLO中的Volume也就是容量目标是否可以达成。对于一般的业务系统我们都会用QPS和TPS来表示系统容量得到了容量这个指标你就可以在平时观察应用或系统运行的容量水位情况。比如我们设定容量的SLO是5000 QPS如果日常达到4500也就是SLO的90%,我们认为这个水位状态下,就要启动扩容,提前应对更大的访问流量。
容量压测的另一个作用,就是看在极端的容量场景下,验证我们前面说到的限流降级策略是否可以生效。
我们看上面电商交易的关键路径图以Detail商品详情页和Comment商品评论这两个应用之间的弱依赖关系为例。从弱依赖的原则上讲如果Comment出现被调用次数过多超时或失败是不能影响Detail这个核心应用的这时我们就要看这两个应用之间对应的降级策略是否生效如果生效业务流程是不会阻塞的如果没有生效那这条链路的成功率就会马上降下来。
另外还有一种场景如果某个非核心应用调用Detail的次数突然激增对于Detail来说它自身的限流保护机制要发挥作用确保自己不会被外部流量随意打垮。
其实类似上述这两种场景,在分布式系统中仅仅靠分析或画架构图是无法暴露出来的,因为业务变更每天都在做,应用之间的调用关系和调用量也在随时发生变化。这时候就需要有容量压测这样的手段来模拟验证,进而暴露依赖关系问题。并且,有些问题必须要在极端场景下模拟才能验证出问题,比如各种服务治理措施,只有在大流量高并发的压力测试下,才能被验证出是否有效。
#### Chaos Engineering-混沌工程
好了,接下来看第二种混沌工程。
我们知道,现在混沌功能非常流行,因为它可以帮助我们做到在线上模拟真实的故障,做线上应急演练,提前发现隐患。很多公司都很推崇这种方法并在积极学习落地中。
其实,刚才我们讲容量压测也提到,容量压测是模拟线上真实的用户访问行为的,但是压测过程中,如果我们模拟极端场景,可能也会造成异常发生,但这时的异常是被动发生的,不过从效果上来讲,其实跟混沌工程就很相似了。只不过,混沌工程是模拟故障发生场景,主动产生线上异常和故障。
那我们怎么把混沌工程应用在SRE中呢一般来说故障发生的层面不同我们采取的方式也会不同。
这里我简单介绍一下比如对于机房故障有些大厂会直接模拟断电这样的场景看机房是否可以切换到双活或备用机房在网络层面我们会模拟丢包或网卡流量打满硬件和系统层面可能故意把一块磁盘写满或者把CPU跑满甚至直接把一个服务器重启应用层面更多地会做一些故障注入比如增加某个接口时延直接返回错误异常线程池跑满甚至一个应用集群直接下线一半或更多机器等。
其实混沌工程也是一个非常复杂的系统化工程,因为要在线上制造故障,或多或少都要对线上业务造成影响,如果模拟故障造成的真实影响超过了预估影响,也要能够快速隔离,并快速恢复正常业务。即使是在稳定性体系已经非常完善的情况下,对于混沌工程的实施也要极为谨慎小心。对于一个模拟策略上线实施,一定是在一个隔离的环境中经过了大量反复验证,包括异常情况下的恢复预案实施,确保影响可控之后,在经过多方团队评审或验证,才最终在线上实施。
从这个角度来讲SRE和混沌工程是什么关系就非常清晰了**混沌工程是SRE稳定性体系建设的高级阶段**一定是SRE体系在服务治理、容量压测、链路跟踪、监控告警、运维自动化等相对基础和必需的部分非常完善的情况下才会考虑的。
所以,引入混沌工程手段要非常慎重,我建议大可不必跟风过早引入,还是优先一步步打好基础再做考虑。
### 应该在什么时机做系统验证?
我们有了验证整个系统SLO的手段但是我们可以看到这两个手段都是要在生产系统上直接实施的为了保证我们的业务正常运行那我们应该选择在什么时机以及什么条件下做系统验证呢
我们可以参考Google给出的建议。
核心就是错误预算充足就可以尝试尽量避开错误预算不足的时间段。因为在正常业务下我们要完成SLO已经有很大的压力了不能再给系统稳定性增加新的风险。
同时,我们还要评估故障模拟带来的影响,比如,是否会损害到公司收益?是否会损害用户体验相关的指标?如果造成的业务影响很大,那就要把引入方案进行粒度细化,分步骤,避免造成不可预估的损失。
这里,我和团队通常的做法,就是选择凌晨,业务量相对较小的情况下做演练。这样即使出现问题,影响面也可控,而且会有比较充足的时间执行恢复操作,同时,在做较大规模的全站演练前,比如全链路的压测,会做单链路和单业务的单独演练,只有单链路全部演练通过,才会执行更大规模的多链路和全链路同时演练。
总之,生产系统的稳定性在任何时候,都是最高优先级要保证的,决不能因为演练导致系统异常或故障,这也是不被允许的。所以,一定要选择合适的时机,在有充分准备和预案的情况下实施各类验证工作。
## 总结
今天我们结合一个电商案例讨论了在落地SLO时还要考虑的一些实际因素。你需要重点掌握以下4点
1. 先设定核心链路的SLO然后根据核心链路进行SLO的分解。
1. 确定一个系统的核心链路,关键是确认核心应用和非核心应用,以及强弱依赖关系。这个过程在初始执行时,需要大量人工投入和分析,但是这个过程不能忽略。
1. 强依赖的核心应用SLO必须与核心链路SLO一致弱依赖的非核心应用SLO可以降低但是必须要有对应的限流降级等服务治理手段。
1. 通过容量压测和混沌工程等手段,对上述过程进行验证,但是一定要在错误预算充足的情况下执行。
## 思考题
最后,给你留一个思考题。
我们知道不同的业务场景考虑的限制因素也是不同的对SLO设定也是一样的。本节课我们分享了一个电商业务应该要考虑的因素你是不是可以按照这个思路分享一个不同于电商的业务场景应该或可能要考虑哪些特殊因素呢
期待在留言区看到你的思考,也欢迎你把今天的内容分享给身边的朋友。
我是赵成,我们下节课见。