copy from github
This commit is contained in:
parent
6dcf00e566
commit
bc06b6d387
|
@ -0,0 +1,2 @@
|
|||
# 第一章
|
||||
本章暂缺。
|
|
@ -0,0 +1,13 @@
|
|||
# 第十章 基于时间序列数据进行有效报警
|
||||
|
||||
监控处于整个生产环境需求金字塔模型(参见[第三部分 具体实践](p3.md))的最底层。监控是运营一个可靠的稳定服务不可缺少的部分。
|
||||
|
||||
***本章主要讲Google的内部监控系统`borgmon`, `Prometheus`是`borgmon`的一个开源实现***
|
||||
|
||||
## 应用软件的监控埋点
|
||||
|
||||
Google内部产生的每个二进制文件中都默认包含一个HTTP服务,同时每种主流编程语言都提供了一个编程接口可以自动注入暴露指定的程序变量。软件服务器作者可以随后对这个变量进行简单地增加操作,或者直接修改这个变量的值。Go语言中的expvar标准库和他的JSON输出格式也提供了类似的API。
|
||||
|
||||
## 监控指标的收集
|
||||
|
||||
一套服务发现体系可以降低监控系统的配置维护难度,允许监控系统自动扩展。
|
|
@ -0,0 +1,71 @@
|
|||
# 第十一章 on-call轮值
|
||||
|
||||
on-call轮值是很多运维和研发团队的重要职责,这项任务的目标是保障服务的可靠性和可用性。
|
||||
|
||||
on-call工程师的响应时间通常跟业务的可靠性有关。不同的SLO响应时间不同。
|
||||
|
||||
## on-call工作平衡
|
||||
|
||||
SRE团队对on-call工作的质量(工作压力)和数量有明确的要求,这两个维度必须保持在一个可持续的水平上。
|
||||
|
||||
### 数量上保持平衡
|
||||
|
||||
SRE团队50%的时间花在软件工程上,其余的时间中, 不超过25%的时间来on-call,另外25%时间来处理其他运维工作。
|
||||
|
||||
SRE更多地推荐团队:
|
||||
|
||||
1. 避免夜间任务影响健康(多地时差)
|
||||
|
||||
2. 限制人员数量,保障对生产环境的熟悉程度
|
||||
|
||||
### 质量上保持平衡
|
||||
|
||||
每次on-call值班过程中,轮值工程师必须有足够的时间处理紧急事件和后续跟进工作,如写事后报告。
|
||||
|
||||
一系列根本原因或相关的事件和报警信息并且这些事件应该在同一个事后报告中讨论,这些事件称为紧急事件。
|
||||
|
||||
平均处理一个生产环境事件需要约6小时,所以每12小时最多2个紧急事件。
|
||||
|
||||
### 补贴措施
|
||||
|
||||
为保障团队按需参与on-call,同时避免过量on-call带来的问题(如项目开发时间不够或疲劳过度), 管理层需要考虑针对工作时间之外的on-call工作给予合理的补贴。
|
||||
|
||||
## 安全感
|
||||
|
||||
为确保on-call工程师保持理性、专注、有意识地进行认知类活动而不是依赖直觉、自动化、快速行动, 必须减轻on-call所带来的压力感。
|
||||
|
||||
让on-call可以使用以下资源来寻求外部帮助以减轻on-call压力:
|
||||
|
||||
- 清晰的问题升级路线
|
||||
|
||||
- 清晰定义的应急事件处理步骤
|
||||
|
||||
- 无指责,对事不对人的文化氛围
|
||||
|
||||
生产系统对应的开发团队也会参与on-call轮值,SRE团队永远可以寻求这些伙伴团队的帮助。
|
||||
|
||||
对于非常复杂,需要多团队参与,或经过一段时间调查仍不能确定恢复时间的问题,应考虑启用某种正式的应急事务流程。
|
||||
|
||||
在应急事件处理解释时,应总结处理事件过程中做的好与不好的地方, 并采取措施避免再次发生同样的问题。
|
||||
|
||||
## 避免运维压力过大
|
||||
|
||||
当SRE团队需要50%以上的时间来处理运维工作时,那么SRE团队的运维工作压力就过大。
|
||||
|
||||
通过以下途径解决运维工作压力过大的问题:
|
||||
|
||||
- SRE团队和管理层负责在季度工作计划中加入一些应对措施,如从其他团队临时抽调一名有经验的SRE。
|
||||
|
||||
- 运维压力过载应该是基于数据且可量化的。
|
||||
|
||||
- 确保监控配置没有错误,报警策略必须跟服务的SLO目标一致。
|
||||
|
||||
- 控制on-call工程师收到的针对同一起事故的报警数量。
|
||||
|
||||
- SRE和研发团队设立共同的目标,解决运维压力。
|
||||
|
||||
- 极端情况下,SRE可选择停止支持某个服务,由开发团队负责on-call轮值或者与开发团队共同承担运维压力直至运维压力降低。
|
||||
|
||||
## 避免运维压力不够
|
||||
|
||||
运维压力不够也是一个不良现象,应控制SRE团队的大小,保证每个工程师每个季度必须至少参与一次(最好两次)on-call,同时每年举办一次灾难恢复演习(DiRT)
|
|
@ -0,0 +1,103 @@
|
|||
# 第十二章 有效的故障排查手段
|
||||
|
||||
值得警惕的是,理解一个系统应该如何工作并不能使人成为专家,只能靠调查系统为何不能正常工作才行。 ---- Brian Redman
|
||||
|
||||
系统正常,只是该系统无数异常情况下的一种特例。 ---- John Allspaw
|
||||
|
||||
## 故障排查理想模型
|
||||
|
||||
![avtar](img/12.1.guzhangpaichaliucheng.png)
|
||||
|
||||
## 常见故障排查陷阱
|
||||
|
||||
- 关注了错误的现象或者错误地理解了系统现象的含义,在错误方向上浪费时间
|
||||
|
||||
- 不能正确修改系统的配置信息、输入信息或者系统运行环境,造成不能安全有效地测试假设
|
||||
|
||||
- 将问题过早地归结为极为不可能的因素或念念不忘之前曾发生过的系统问题,认为一旦发生过一次,就有可能再发生
|
||||
|
||||
- 试图解决与当前系统问题相关的一些问题,却没有认识到这些其实只是巧合,或者这些问题其实是由当前系统问题造成的
|
||||
|
||||
如何避免这些陷阱
|
||||
|
||||
- 要避免前两点,需要更详细地学习系统的运行原理,同时了解分布式系统运行的基本模式
|
||||
|
||||
- 要避免第三点,需要记住不是所有失败情况出现的概率都相同,当所有可能都存在,应该优先最简单的。
|
||||
|
||||
- 要避免第四点,需要记住,相关性不等于因果关系
|
||||
|
||||
## 实践
|
||||
|
||||
在实践中,故障排查过程不一定与理想模型一致。
|
||||
|
||||
### 故障报告
|
||||
|
||||
有效的故障报告应该写清楚预期是什么,实际结果是什么,以及如何重现。报告应使用统一格式,并存储进故障库,应该为每一个错误报告提交一个BUG,而不是直接报告给具体的人。
|
||||
|
||||
### 定位
|
||||
|
||||
收到一个错误报告时,应先明确其严重程度,对于大型问题,首先要尽最大可能让系统恢复服务并保存故障现场,如日志等。
|
||||
|
||||
如果一个BUG有可能导致不可恢复的数据损失,停止整个系统比让系统继续运行更好。
|
||||
|
||||
### 检查
|
||||
|
||||
必须能够检查系统中每个组件的工作状态以便了解整个系统是不是在正常工作:
|
||||
|
||||
1. 查看监控记录
|
||||
|
||||
2. 查看日志
|
||||
|
||||
3. 暴露目前的系统状态
|
||||
|
||||
4. 需要一个使用该系统的真是客户端
|
||||
|
||||
### 诊断
|
||||
|
||||
1. 将问题分解,逐个检查系统的每个组件,知道系统的最底层,对于大型系统可以使用对分法。
|
||||
|
||||
2. 找出系统目前正在执行什么,然后通过询问系统为什么正在做这些操作,以及系统的资源都被用在了哪里。
|
||||
|
||||
3. 检查最近对系统的修改
|
||||
|
||||
4. 使用针对具体系统开发的诊断工具和诊断系统
|
||||
|
||||
### 测试和修复
|
||||
|
||||
设计测试的一些考量
|
||||
|
||||
- 一个理想的测试应该具有互斥性,通过这个测试可以将一组假设推翻,同时确认另一组假设。
|
||||
|
||||
- 先测试最可能的情况,按照可能发生的顺序执行测试,同时考虑该测试对系统的危险性
|
||||
|
||||
- 某项测试可能产生误导的结果
|
||||
|
||||
- 执行测试可能带来副作用
|
||||
|
||||
- 某些测试无法得出准确的结论,只是建议性的
|
||||
|
||||
明确记录执行了哪些测试以及测试的结果。
|
||||
|
||||
#### 神奇的负面结果
|
||||
|
||||
负面结果指一项实验的预期结果没有出现,也就是该实验没有成功。
|
||||
|
||||
- 负面结果不应被忽略或被轻视。
|
||||
|
||||
- 一项实验中出现的负面结果可以明确高速我们生产环境中的信息,设计理念对错或现有系统的性能极限,并可能被再次或不同团队使用。
|
||||
|
||||
- 工具和方法可能超越目前的试验,为未来的工作提供帮助。
|
||||
|
||||
- 公布负面结果有助于提升整个行业的数据驱动风气,公布拟的实验结果,哪怕它是失败的。
|
||||
|
||||
### 治愈
|
||||
|
||||
当你最终确定了某个因素是问题根源时,应该将系统中出错的部分、定位问题的过程、修复问题的方法和防止问题再次发生的策略等记录下来。
|
||||
|
||||
## 使故障排查更简单
|
||||
|
||||
简化和加速故障排查过程的最基本方法是:
|
||||
|
||||
- 增加可观察性,在实现之初就给每个组件增加白盒监控指标和结构化日志
|
||||
|
||||
- 利用成熟的,观察性好的组件接口设计系统
|
|
@ -0,0 +1,21 @@
|
|||
# 第十三章 紧急事件响应
|
||||
|
||||
东西总是要坏的,这就是生活。
|
||||
|
||||
## 紧急事件响应的几点原则
|
||||
|
||||
1. 不要害怕问题,所有问题都有解决方案
|
||||
|
||||
2. 当想不到解决办法时,及时快速的问一切能给你提供帮助的人求助
|
||||
|
||||
3. 为事故保留记录,记录一定要诚实,要事无巨细
|
||||
|
||||
4. 提出关键问题,寻找如何能在战术及战略上避免事故的发生
|
||||
|
||||
5. 公布和维护事故报告,分享你从中学到的知识
|
||||
|
||||
6. 事故结束后,确保自己和他人切实完成事故中总结的待办事项
|
||||
|
||||
7. 提出那些大的,甚至不可能的问题
|
||||
|
||||
8. 鼓励主动测试
|
|
@ -0,0 +1,67 @@
|
|||
# 第十四章 紧急事故管理
|
||||
|
||||
有效的紧急事故管理是控制事故影响和迅速恢复运营的关键因素。
|
||||
|
||||
## 紧急事故的流程管理要素
|
||||
|
||||
紧急事故流程管理的技巧和手段都是为了让这些富有热情的人能够真正帮上忙。
|
||||
|
||||
Incident Command System是一个紧急事故管理系统。
|
||||
|
||||
### 嵌套式职责分离
|
||||
|
||||
在事故处理中,让每个人清楚自己的职责是非常重要的,系统中有如下角色可以分配:
|
||||
|
||||
1. 事故总控。 负责掌握此次事故的概要信息,组建事务处理团队,分配并协调处理工作
|
||||
|
||||
2. 事务处理团队。 团队负责人与总控沟通并指挥团队具体执行合适的事务来解决问题,事务处理团队是一次事故中唯一能对系统做修改的团队
|
||||
|
||||
3. 发言人。 本次事故处理团队的公众发言人,职责包括向相关人员发送周期性通知,同时维护目前的事故文档,保证其正确性和信息及时性。
|
||||
|
||||
4. 规划负责人。 为事务处理团队提供支持。负责一些持续性的工作,同时负责记录在处理过程中对系统进行的特殊操作,以便未来事故结束后可以复原。
|
||||
|
||||
### 控制中心
|
||||
|
||||
让处理问题的全部成员到同一个地方办公,并使用聊天工具和e-mail进行远程沟通。
|
||||
|
||||
### 实时事故状态文档
|
||||
|
||||
事故总控负责人维护一个实时事故文档,该文档最好可以多人同时编辑。
|
||||
|
||||
### 明确公开的职责交接
|
||||
|
||||
当超出工作时间以后,事故负责人的职责必须明确公开的进行交接,交接结果应该宣布给其他正在处理事故的人,明确目前的事故处理负责人
|
||||
|
||||
## 什么时候对外宣布事故
|
||||
|
||||
当下面任何一条条件满足时,事故应该被及时公布
|
||||
|
||||
- 需要引入第二个团队来帮助处理问题
|
||||
|
||||
- 事故影响了最终用户
|
||||
|
||||
- 在集中分析一小时后,依然没有得到解决
|
||||
|
||||
## 事故流程管理的最佳实践
|
||||
|
||||
- 划分优先级
|
||||
控制影响范围,恢复服务,同时为根源调查保存现场
|
||||
|
||||
- 事前准备
|
||||
事先和所有事故处理参与者一起准备一套流程
|
||||
|
||||
- 信任
|
||||
充分相信每个事故处理参与者,分配职责后让他们自主行动
|
||||
|
||||
- 反思
|
||||
在事故处理过程种注意自己的情绪和精神状态,如果发现自己开始惊慌失措或者感到压力难以承受,应该寻求更多帮助。
|
||||
|
||||
- 考虑替代方案
|
||||
周期性的审视目前的情况,重新评估目前的工作是应该继续执行还是需要执行其他更重要或更紧急的事情
|
||||
|
||||
- 练习
|
||||
平时不断地使用这项流程,直到习惯成自然
|
||||
|
||||
- 换位思考
|
||||
每次故障可以换一个不同的职责试试,鼓励每个团队成员熟悉流程中的其他角色
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# 第十五章 事后总结:从失败中学习
|
||||
|
||||
书写事后总结的主要目的是为了保证该事故被记录下来,理清所有根源问题,确保实施有效的措施使得未来重现的几率和影响降低甚至避免重现。
|
||||
|
||||
书写事后总结不是一种惩罚措施,而是给整个公司一个学习的机会。
|
||||
|
||||
## 基本事后总结条件
|
||||
|
||||
事后总结应对事不对人,重点关注如何定位造成这次事件的根本问题。
|
||||
|
||||
- 用户可见的宕机时间或者服务质量降级程度达到一级标准
|
||||
|
||||
- 任何类型的数据丢失
|
||||
|
||||
- on-call工程师需要人工介入的事故,包括回滚、切换用户流量等
|
||||
|
||||
- 问题解决耗时超过一定限制
|
||||
|
||||
- 监控问题,预示着问题是由人工发现而非报警系统
|
||||
|
||||
## 协作和只是共享
|
||||
|
||||
事后总结工作流程的每一步都包括团队协作和知识共享。
|
||||
|
||||
事后总结的过程还包括正式的评审和发布过程,团队首先内部发布,同时依据如下条件评审:
|
||||
|
||||
- 关键的灾难数据是否已被收集并保存
|
||||
|
||||
- 本次事故的影响评估是否完整
|
||||
|
||||
- 造成事故的根源问题是否足够深入
|
||||
|
||||
- 文档中记录的任务优先级是否合理,能否及时解决根源问题
|
||||
|
||||
- 事故处理的过程是否共享给了所有相关部门
|
||||
|
||||
## 建立事后总结文化
|
||||
|
||||
SRE通过组织一些集体活动来更好的建立事后总结文化:
|
||||
|
||||
- 分享本月最佳事后总结
|
||||
|
||||
- 组建事后总结讨论小组
|
||||
|
||||
- 组织事后总结阅读俱乐部
|
||||
|
||||
- 参见命运之轮游戏--再现事后总结场景,扮演其中的角色进行演习活动。
|
||||
|
||||
对投入产出比的质疑是对引入事后总结机制的最大阻力,以下策略来帮助面对这个挑战:
|
||||
|
||||
- 逐渐引入事后总结流程,首先进行几次完整和成功的事后总结,证明其价值并确定书写的条件
|
||||
|
||||
- 确保有效的书面总结,提供奖励和庆祝
|
||||
|
||||
- 鼓励公司高级管理层认可和参与其中
|
|
@ -0,0 +1,29 @@
|
|||
# 第十六章 跟踪故障
|
||||
|
||||
提高可靠性的唯一可靠方法论是建立一个基线,同时不断跟踪改变。
|
||||
|
||||
系统性地从过去发生过的问题中学习是服务运维的必要手段。
|
||||
|
||||
## Outalator
|
||||
|
||||
outalator是一个故障跟踪工具。
|
||||
|
||||
### 聚合
|
||||
|
||||
将多个报警信息“聚合”成一个单独的故障能够有效解决一个故障触发多个报警的问题。
|
||||
|
||||
### 加标签
|
||||
|
||||
不是每个报警信息都代表一次故障,可以添加标签给报警信息来进行区分
|
||||
|
||||
### 分析
|
||||
|
||||
SRE不仅仅是响应和处理故障,分析历史数据对响应某个故障非常有帮助,数据分析的下一步是找到影响更广泛的问题,而不就仅仅是简单的计数。
|
||||
|
||||
### 报告和公告
|
||||
|
||||
选择一系列故障,将所有故障信息发给其他工程师
|
||||
|
||||
### 未预料到的好处
|
||||
|
||||
能够将某条报警或者某系列报警跟其他某个故障连接起来,可以加快检查速度和通过确认目前的确有某项故障以降低其他团队的压力。
|
|
@ -0,0 +1,2 @@
|
|||
# 第二章
|
||||
本章暂缺
|
|
@ -0,0 +1,70 @@
|
|||
# 第三章 拥抱风险
|
||||
|
||||
不必追求100%的服务可靠性,过分追求服务的可靠性会带来成本的巨大提升,同时减少了新功能的数量及更新频率。
|
||||
|
||||
用户本身设备就有可靠性损失,99.99%与99.999%在用户体验上并无太大区别。
|
||||
|
||||
## 服务可靠性成本
|
||||
|
||||
高昂的成本主要存在以下两个维度:
|
||||
|
||||
- 冗余服务器/计算资源成本。
|
||||
- 机会成本。 构建减少风险的系统或功能,而非用户直接可用的功能的工程资源成本。
|
||||
|
||||
## 度量服务的风险
|
||||
|
||||
度量服务的风险从两个维度,基于时间和基于请求成功率。
|
||||
|
||||
### 基于时间的可用性公式
|
||||
|
||||
可用性=系统正常时间/(系统正常运行时间+停机时间)
|
||||
|
||||
### 基于请求成功率的可用性公式
|
||||
|
||||
**此公式对于分布式服务或定时任务更有意义**
|
||||
|
||||
可用性=成功请求数/总请求数
|
||||
|
||||
## 服务的风险容忍度
|
||||
|
||||
服务的风险容忍度通常是直接根据基本产品或服务的定义建立的。
|
||||
|
||||
### 消费者服务
|
||||
|
||||
评价服务风险容忍度时,有以下几个因素:
|
||||
|
||||
- 可用性目标
|
||||
根据功能及市场定位来制定,快速发展的服务较低而企业服务较高。
|
||||
|
||||
- 故障类型
|
||||
不同故障对服务的影响不同
|
||||
|
||||
- 成本
|
||||
提升可靠性会带来一定收益并投入成本,当收益高于成本就是合理投资
|
||||
|
||||
- 其他服务指标
|
||||
比如服务延迟
|
||||
|
||||
### 基础设施服务
|
||||
|
||||
基础设施服务与消费者服务的一个根本区别是,基础设施组件有多个用户,而他们通常有很多不同的需求。
|
||||
|
||||
评价服务风险容忍度时,有以下几个因素:
|
||||
|
||||
- 可用性目标水平
|
||||
需要分析每个用户的不同需求来划分服务水平
|
||||
|
||||
- 故障类型
|
||||
|
||||
- 成本
|
||||
依据不同的服务水平分割成多个基础设施服务,在多个独立的服务水平上提供该服务,是一种在符合成本效益条件下满足这些竞争性约束的方式。
|
||||
|
||||
## 使用错误预算
|
||||
|
||||
使用错误预算的好处是能够激励产品研发和SRE一起找出创新和可靠性之间合理的平衡点。
|
||||
|
||||
1. 定义一个服务水平目标(SLO), 确定正常服务时间
|
||||
|
||||
2. 通过监控系统测算实际在线时间
|
||||
3. 正常服务目标时间-实际在线时间=不可靠预算
|
||||
4. 只要正常在线时间高于SLO,就可以发布新版本
|
|
@ -0,0 +1,101 @@
|
|||
# 第四章 服务质量目标
|
||||
|
||||
本章描述了SRE团队在指标建模、指标选择以及指标分析上采用的基本框架。
|
||||
|
||||
## 服务质量术语
|
||||
|
||||
- 指标 `SLI(Service Level Indicator)`
|
||||
服务质量指标是一个服务的某项服务质量的具体量化指标。
|
||||
|
||||
- 目标 `SLO(Service Level Objective)`
|
||||
服务质量目标是服务的某个SLI的目标值或目标范围。SLO的定义是 SLI≤目标值,或范围下限≤SLI≤范围上限。
|
||||
|
||||
- 协议 `SLA(Service Level Agreement)`
|
||||
服务质量协议是服务与用户之间的一个明确的或者不明确的协议。描述在达到或者未达到SLO之后的后果。
|
||||
|
||||
## 指标`SLI`在实践中的应用
|
||||
|
||||
常见服务的几大类SLI
|
||||
|
||||
- 用户可见的服务系统
|
||||
通常关心可用性、延迟、吞吐量
|
||||
|
||||
- 存储系统
|
||||
通常强调: 延迟、可用性、数据持久性
|
||||
|
||||
- 大数据系统
|
||||
通常关心吞吐量和端到端延迟
|
||||
|
||||
- 所有系统
|
||||
都关注正确性
|
||||
|
||||
### 收集指标
|
||||
|
||||
指标收集分为服务端和客户端。服务端主要依靠监控系统(promethues)和日志分析系统,客户端主要依靠页面埋点和其他收集系统(如专门收集手机app指标的系统)。
|
||||
|
||||
对于大部分指标,汇总时应当以“分布”而不是平均值来定义。
|
||||
|
||||
### 指标标准化
|
||||
|
||||
应该标准化一些常见的SLI,任何符合标准定义模板的服务可以直接使用而不需要再次评估定义。
|
||||
|
||||
- 汇总间隔
|
||||
- 汇总范围
|
||||
- 度量频率
|
||||
- 包含的请求
|
||||
- 数据获取方式
|
||||
- 数据访问延迟
|
||||
|
||||
## 目标`SLO`在实践中的应用
|
||||
|
||||
应从用户最关心的方面入手而不是从能度量什么入手。先制定目标,从而反推出指标`SLI`。
|
||||
|
||||
### 目标定义
|
||||
|
||||
定义SLO的几个要素:
|
||||
|
||||
- SLO应该具体指出其是如何度量的,以及有效条件。
|
||||
|
||||
- 应该使用错误预算而不是要求SLO能被100%满足。
|
||||
|
||||
- 通过每日(周)对SLO达标成都的监控可以展示一个趋势,在重大问题发生器得到预警。
|
||||
|
||||
- SLO不达标的频率与错误预算进行对比,利用差值来指导新版本的发布。
|
||||
|
||||
### 目标的选择
|
||||
|
||||
选择目标SLO不是一个纯粹的技术活动,因为这里还涉及产品及业务层的决策,SLI和SLO(甚至SLA)的选择都应直接反应该决策
|
||||
|
||||
选择目标的几点要素:
|
||||
|
||||
- 不要仅以当前状态为基础选择目标
|
||||
- 保持简单
|
||||
- 避免绝对值
|
||||
- SLO越少越好
|
||||
- 不追求完美
|
||||
- 小心使用SLO
|
||||
|
||||
### SLI和SLO作为控制手段
|
||||
|
||||
SLI和SLO在决策系统运维是非常有用:
|
||||
|
||||
1. 监控并度量系统的SLI
|
||||
2. 比较SLI与SLO以决定是否需要执行操作
|
||||
3. 如果需要操作,决定执行什么操作以满足目标SLO
|
||||
4. 执行操作
|
||||
|
||||
### 使用SLO建立用户预期
|
||||
|
||||
用户经常希望知道他们可以预期的服务质量以便理解服务是否能够满足他们的需求,通过公布SLO可以设置用户对系统的预期。
|
||||
|
||||
使用以下策略让用户拥有正确的预期:
|
||||
|
||||
- 留出一定的安全区
|
||||
|
||||
- 实际SLO不要过高
|
||||
|
||||
## 协议`SLA`在实践中的应用
|
||||
|
||||
由业务部门和法务部门选择合适的后果条款,SRE帮主这些部门理解SLA和SLO达标的概率和困难程度。
|
||||
|
||||
最好在用户宣传方面偏于保守。
|
|
@ -0,0 +1,57 @@
|
|||
# 第五章 减少琐事
|
||||
|
||||
***如果系统正常运转中需要人工干预,应该将此视为一种BUG。***
|
||||
***“正常”的定义会随系统的进步而不断改变。***
|
||||
|
||||
SRE要把更多的时间花费在长期项目研发上而非琐事(日常运维)中。
|
||||
|
||||
## 琐事的定义
|
||||
|
||||
琐事不仅仅代表“我不喜欢的工作”。
|
||||
|
||||
琐事就是运维服务中手动性的、重复性的、可以被自动化的、战术性的、没有持久价值的、与服务呈线性关系增长的工作。
|
||||
|
||||
流程开销不是琐事,如团队会议、目标的建立和评估、每周总结以及HR的书面工作。
|
||||
|
||||
## SRE的工作时间分配
|
||||
|
||||
SRE的一个公开目标是保持每个SRE工作时间中的运维工作(琐事)的比例低于50%。SRE至少花50%的时间在工程项目上,以减少未来的琐事或增加服务功能(提高可用性、利用率、性能)。
|
||||
|
||||
### 什么是工程工作
|
||||
|
||||
工程工作是一种新颖的,本质上需要主观判断的,符合长期战略的,会对你的服务进行长久性改善的工作。
|
||||
|
||||
## SRE的活动分类
|
||||
|
||||
典型的SRE活动分为以下几类:
|
||||
|
||||
- 软件工程
|
||||
编写或修改代码,以及所有其他相关性设计和文档的工作
|
||||
- 系统工程
|
||||
配置生产系统,修改现存配置,或者用一种通过一次性工作产生持久的改进的方法来书写系统文档。
|
||||
- 琐事
|
||||
与运维服务相关的重复性的、手工的劳动
|
||||
- 流程负担
|
||||
与运维服务不直接相关的行政工作
|
||||
|
||||
## 琐事的有害因素
|
||||
|
||||
在SRE工作种,一定量的琐事是不可避免的,如果琐事特别繁重,那就应该非常担忧,大声抱怨。在许多琐事有害的原因种,以下因素要被考虑:
|
||||
|
||||
- 职业停滞
|
||||
|
||||
- 士气低落
|
||||
|
||||
- 造成误解
|
||||
|
||||
- 进展缓慢
|
||||
|
||||
- 开创先例,造成琐事越来越多
|
||||
|
||||
- 促进摩擦产生
|
||||
|
||||
- 违反承诺
|
||||
|
||||
## 总结
|
||||
|
||||
让我们多创新,少干琐事吧。
|
|
@ -0,0 +1,71 @@
|
|||
# 第六章 分布式系统的监控
|
||||
|
||||
|
||||
## 术语定义
|
||||
|
||||
关于监控的一些术语定义。
|
||||
|
||||
### 监控(monitoring)
|
||||
|
||||
收集、处理、汇总,并且显示关于某个系统的实时量化数据。
|
||||
|
||||
### 白盒监控(white-box monitoring)
|
||||
|
||||
依靠系统内部暴露的一些性能指标进行监控。
|
||||
|
||||
### 黑盒监控(black-box monitoring)
|
||||
|
||||
通过测试某种外部用户可见的系统行为进行监控。
|
||||
|
||||
### 监控台页面(dashboard)
|
||||
|
||||
提供某个服务核心指标一览服务的应用程序。
|
||||
|
||||
### 警报(alert)
|
||||
|
||||
目标对象是某个人发向某个系统地址的一个通知。
|
||||
|
||||
### 根源问题(root cause)
|
||||
|
||||
指系统(软件或流程)中的某个缺陷,如果这个缺陷被修复,就可以保证这个问题不会再以同样的方式发生。
|
||||
|
||||
### 节点或者机器(node/machine)
|
||||
|
||||
指物理机、虚拟机或者容器内运行的某个实例。
|
||||
|
||||
### 推送(push)
|
||||
|
||||
关于某个服务正在运行的软件或者其配置文件的任何改动。
|
||||
|
||||
## 监控系统的四个黄金指标
|
||||
|
||||
1. 延迟
|
||||
服务处理某个请求需要的时间。
|
||||
2. 流量
|
||||
使用系统中某个高层次的指标对系统负载需求所进行的度量。
|
||||
3. 错误
|
||||
请求失败的速率(包括显示或隐式失败)。
|
||||
4. 饱和度
|
||||
服务容量有多满。通常是系统中目前最为受限的某种资源的某个具体指标的度量。
|
||||
|
||||
## 监控系统设计理念
|
||||
|
||||
监控系统设计的核心理念是简化,直到不能再简化。
|
||||
|
||||
- 对于最能反映真是故障的规则应该越简单越好,可预测性强,非常可靠
|
||||
|
||||
- 对于不常用的数据收集汇总以及警报配置应该定时删除
|
||||
|
||||
- 收集到的信息,但是没有暴露给任何监控台或者没有被任喝警报规则使用的,应该定时删除。
|
||||
|
||||
度量指标时应使用合适的精度,系统的不同部分应该以不同的精度度量。
|
||||
|
||||
## 应对警报的深层理念
|
||||
|
||||
1. 紧急警报应该是立即需要进行某种操作的,每天只能进入紧急状态几次,避免导致狼来了效应。
|
||||
|
||||
2. 紧急警报应该是可以具体操作的
|
||||
|
||||
3. 紧急警报的回复都应该需要某种智力分析过程。对于只需要一个固定的机械动作的警报,不应成为紧急警报。
|
||||
|
||||
4. 紧急警报都应该是关于某个新问题的,不应该彼此重叠
|
|
@ -0,0 +1,29 @@
|
|||
# Google的自动化系统的演进
|
||||
|
||||
“黑科技”之外,就只剩下自动化和机械化了。 ---- Federico Garcia Lorca
|
||||
|
||||
## 自动化的价值
|
||||
|
||||
- 一致性
|
||||
一致性地执行范围明确、步骤已知的程序是自动化的首要价值。
|
||||
- 平台性
|
||||
通过正确地设计和实现自动化系统可以提供一个可以扩展的,广泛适用的,甚至可能带来额外收益的平台。
|
||||
一个平台也将错误集中化。
|
||||
- 修复速度更快
|
||||
成功运行的自动化可以降低一些常见故障的平均修复时间(MTTR)。
|
||||
- 行动速度更快
|
||||
机器的反应速度快过人工。
|
||||
- 节省时间
|
||||
|
||||
## 自动化的演进路径
|
||||
|
||||
1. 没有自动化,纯手工操作
|
||||
|
||||
2. 外部维护的系统特定的自动化
|
||||
|
||||
3. 外部维护的通用自动化系统
|
||||
|
||||
4. 内部维护的通用自动化系统
|
||||
|
||||
5. 不需要任何自动化的系统
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# 第八章 发布工程
|
||||
|
||||
发布工程(Release Engineering)是软件工程内部一个专注于构建和交付软件的学科。
|
||||
|
||||
## 发布工程哲学
|
||||
|
||||
发布工程师的日常工作是由下列四个主要的工程与服务哲学指导的。
|
||||
|
||||
### 自助服务模型
|
||||
|
||||
发布工程师开发工具,制定最佳实践,以便让产品研发团队可以自己掌握和执行自己的发布流程。
|
||||
|
||||
### 追求速度
|
||||
|
||||
频繁的发布可以使每个版本之间的变更更少,这种方式使测试和调试变得简单。
|
||||
|
||||
### 密闭性
|
||||
|
||||
构建工具必须确保一致性和可重复性,构建过程使密闭的,不应受到构建服务器上安装的第三方类库或者其他软件工程的影响。
|
||||
|
||||
### 强调策略和流程
|
||||
|
||||
多层安全和访问控制机制可以确保发布过程中只有指定的人才能执行指定的操作。
|
||||
|
||||
主要关注以下操作:
|
||||
|
||||
- 批准源代码改动----通过源代码仓库中的配置文件决定
|
||||
|
||||
- 指定发布流程中需要执行的具体操作
|
||||
|
||||
- 创建新的发布版本
|
||||
|
||||
- 批准初始的继承请求以及后续的cherry picking请求
|
||||
|
||||
- 实际部署某个发布(release)版本
|
||||
|
||||
- 修改某个项目的构建配置文件
|
||||
|
||||
## Google的持续集成方案
|
||||
|
||||
参见 78-82 页。
|
|
@ -0,0 +1,49 @@
|
|||
# 第九章 简单化
|
||||
|
||||
可靠性只有靠对最大程度的简化不断追求而得到。 ---- C.A.R.Hoare, Turing Award lecture
|
||||
|
||||
软件系统本质上是动态和不稳定的。SRE的工作室在系统的灵活和稳定性上维持平衡。
|
||||
|
||||
## 系统的灵活性与稳定性
|
||||
|
||||
有时候为灵活性而牺牲稳定性是有意义的。
|
||||
|
||||
SRE通过创造流程、实践以及工具来提高软件的可靠性,同时SER需要最小化这些工作对于开发人员灵活性造成的影响。
|
||||
|
||||
## 乏味是一种美德
|
||||
|
||||
我们不想要自发性和有趣的程序,我们希望这些程序按设计执行,可以预见性的完成商业目标。
|
||||
|
||||
关注必要复杂度和意外复杂度之间的区别非常关键,必要复杂度是一个给定情况所固有的复杂度,不能从该问题的定义中移除;意外复杂度是不固定的,可以通过工程上的努力来解决。
|
||||
|
||||
为最小化意外复杂度,SRE团队应该:
|
||||
|
||||
- 在他们所负责的系统中引入意外复杂度时,及时提出抗议
|
||||
|
||||
- 不断努力消除正在接手的和已经负责运维的系统的复杂度
|
||||
|
||||
## 我绝不放弃我的代码
|
||||
|
||||
SRE推崇保证所有的代码都有必须存在的目的的实践。
|
||||
|
||||
## 负代码行作为一个指标
|
||||
|
||||
添加到项目中的每行代码都可能引入新的缺陷和错误。
|
||||
较小的项目容易理解,也更容易测试,而且通常缺陷也少。应该按需删除无用的代码。
|
||||
对于增加新功能的需求,应该持保守态度。
|
||||
|
||||
## 最小API
|
||||
|
||||
不是在不能添加更多的时候,而是在没有什么可以去掉的时候,才能达到完美。
|
||||
书写一个明确的,最小的API是管理软件系统管理简单性必要的部分。
|
||||
|
||||
## 模块化
|
||||
|
||||
在二进制文件之间或二进制文件与配置之间推行松耦合,是一种同时提高开发人员灵活性和系统稳定性的简化模式。
|
||||
|
||||
模块化同样适用用分布式系统与数据的设计。
|
||||
|
||||
## 发布简单化
|
||||
|
||||
简单的发布流程要比复杂的发布流程更好。如果发布是按更小的批次进行的,我们就可以更有信心地进行更快的发布,因为每个变更在系统中的影响都可以独立理解。
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
|
@ -0,0 +1,5 @@
|
|||
# 第三部分 具体实践
|
||||
|
||||
## 服务可靠度层级模型
|
||||
|
||||
![avatar](img/srlm.png)
|
|
@ -0,0 +1,51 @@
|
|||
# Google SRE 运维解密读书笔记
|
||||
|
||||
# 目录
|
||||
|
||||
## 第一部分 概览
|
||||
|
||||
- [第一章 介绍](1.md)
|
||||
- [第二章 Google生产环境 SRE视角](2.md)
|
||||
|
||||
## 第二部分 指导思想
|
||||
|
||||
- [第三章 拥抱风险](3.md)
|
||||
- [第四章 服务质量目标](4.md)
|
||||
- [第五章 减少琐事](5.md)
|
||||
- [第六章 分布式系统的监控](6.md)
|
||||
- [第七章 Google的自动化系统的演进](7.md)
|
||||
- [第八章 发布工程](8.md)
|
||||
- [第九章 简单化](9.md)
|
||||
|
||||
## 第三部分 具体实践
|
||||
|
||||
- [第十章 基于时间序列数据进行有效报警](10.md)
|
||||
- [第十一章 on-call轮值](11.md)
|
||||
- [第十二章 有效的故障排查手段](12.md)
|
||||
- [第十三章 紧急事件响应](13.md)
|
||||
- [第十四章 紧急事故处理](14.md)
|
||||
- [第十五章 事后总结:从失败中学习](15.md)
|
||||
- [第十六章 跟踪故障](16.md)
|
||||
- [第十七章 测试可靠性](17.md)
|
||||
- [第十八章 SRE部门中的软件工程实践](18.md)
|
||||
- [第十九章 前端服务器的负载均衡](19.md)
|
||||
- [第二十章 数据中心内部的负载均衡系统](20.md)
|
||||
- [第二十一章 应对过载](21.md)
|
||||
- [第二十二章 处理连锁故障](22.md)
|
||||
- [第二十三章 管理关键状态:利用分布式共识来提高可靠性](23.md)
|
||||
- [第二十四章 分布式周期性任务系统](24.md)
|
||||
- [第二十五章 数据处理流水线](25.md)
|
||||
- [第二十六章 数据完整性:读写一致](26.md)
|
||||
- [第二十七章 可靠地进行产品的大规模发布](27.md)
|
||||
|
||||
## 第四部分 管理
|
||||
|
||||
- [第二十八章 迅速培养SRE加入on-call](28.md)
|
||||
- [第二十九章 处理中断性任务](29.md)
|
||||
- [第三十章 通过嵌入SRE的方式帮助团队从运维过载中恢复](30.md)
|
||||
- [第三十一章 SRE与其他团队的沟通与协作](31.md)
|
||||
- [第三十二章 SRE参与模式的演进历程](32.md)
|
||||
|
||||
## 第五部分 结束语
|
||||
|
||||
- [第三十三章 其他行业的实践经验](33.md)
|
|
@ -0,0 +1,9 @@
|
|||
# 第一章 什么是Prometheus
|
||||
|
||||
Prometheus是一个开源的、基于指标的监控系统。
|
||||
|
||||
Prometheus是指标拉取型监控系统
|
||||
|
||||
## Prometheus 架构
|
||||
|
||||
![avtar](img/prometheus.png)
|
Binary file not shown.
After Width: | Height: | Size: 150 KiB |
|
@ -0,0 +1,27 @@
|
|||
# PromQL
|
||||
|
||||
promQL的一些示例与解析。
|
||||
|
||||
#### `up{instance="localhost:9090", job="prometheus"}`
|
||||
|
||||
up 是一个指标名
|
||||
instance 是一个标签,表示被抓取的目标地址
|
||||
job 是一个标签,来自文件`prometheus.yml`的配置项`job_name`
|
||||
|
||||
#### `process_resident_memory_bytes`
|
||||
|
||||
gauge 类型, 服务当前使用的内存,单位字节
|
||||
gauge类型表示当前绝对值很重要
|
||||
|
||||
#### `prometheus_tsdb_head_samples_appended_total`
|
||||
|
||||
counter类型,跟踪事件发生的数量
|
||||
|
||||
`rate(prometheus_tsdb_head_samples_appended_total[1m])`
|
||||
|
||||
计算一分钟内的平均采样数
|
||||
|
||||
rate是一个函数,这里用来计算counter每秒增长的速度
|
||||
|
||||
[1m] 表示取一分钟内的值
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# Prometheus 学习手册
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
python:
|
||||
python3 main.py
|
||||
go:
|
||||
go run main.go
|
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
|
||||
func runHTTPServer()error{
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request){
|
||||
w.Write([]byte("hello world!"))
|
||||
})
|
||||
return http.ListenAndServe("localhost:8080", nil)
|
||||
}
|
||||
|
||||
func main(){
|
||||
err := runHTTPServer()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import http.server
|
||||
from prometheus_client import start_http_server
|
||||
from prometheus_client import Counter
|
||||
|
||||
REQUESTS=Counter('hello_worlds_total', 'hellow worlds requested.')
|
||||
|
||||
EXCEPTIONS=Counter("hello_world_exceptions_total", 'exceptions serving hello world.')
|
||||
|
||||
class MyHandler(http.server.BaseHTTPRequestHandler):
|
||||
@EXCEPTIONS.count_exceptions()
|
||||
def do_GET(self):
|
||||
REQUESTS.inc()
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
self.wfile.write(b"hello world")
|
||||
|
||||
if __name__ == "__main__":
|
||||
start_http_server(8000)
|
||||
server = http.server.HTTPServer(('localhost', 8001), MyHandler)
|
||||
server.serve_forever()
|
Loading…
Reference in New Issue