从刀耕火种到规范化
- 【阶段一】第一家实习公司是一家小型创业公司,公司当时的体量只有几个人,整个开发流程非常粗暴: a. 在本地开发完成后编译打包 b. 通过 ftp 连接服务器,将打包产物上传到云主机
- 【阶段二】在字节跳动实习做第一个项目,当时存在的现象: a. 测试环境 = 本地开发环境 b. 可以随时上线,合代码不需要 review c. 页面的线上问题发现途径基本上是:用户 -> 运营 -> 产品 -> 研发/测试
举个例子,之前发生过一次事故,原因是前端的打包产物通过云服务器的一个功能以数据块的方式注入到容器中,当时这个功能不可用了一段时间,导致整个页面 504。但因为缺少监控的原因没有第一时间发现,例如 5xx 报错率的提升,页面 PV 下降等,最终问题的发现途径变成了:运营反馈给产品,产品再同步给研发
- 【阶段三】建立开发上线流程规范,开始养成服务稳定性意识
- 本地环境、线下环境、产品预发环境的建设,数据上区分线下线上环境
- 代码 review,卡上线权限
- 配置监控与报警
- ...
SRE 的定义
书名为《SRE: Google 运维解密》 ,那么 SRE 是什么?
SRE 是 Site Reliability Engineering,直译为网站可靠性工程,书中没有进行明确的定义,以个人的理解,用通俗的说法来讲是一系列的方法论,是 Google 软件工程师在系统运维过程中得出的运维方案。(比如早期监控是通过脚本检测的方式来实现,后来逐渐演化为一个新的模型,这个模型使用时间序列信息,发展了一种丰富的时间序列信息操作语言,这个系统称为 Borgmon 监控系统)
当我在 2003 年加入 Google 的时候,我的任务就是领导一个由 7 名软件工程师组成的“生产环境维护组” ...... 当年 7 人的团队已经成长为公司内部 1000 余人的 SRE 团队,但是 SRE 团队的指导理念和工作方式还是基本保持了我最初的想法
—— 第一章 介绍
SRE 团队的职责
- 优化
- 可用性改进
- 延迟优化
- 性能优化
- 效率优化
- 变更管理
业务研发的绩效很大程度上通过业务迭代来体现,比如上线了多少需求,页面增加了多少 UV,而 SRE 团队的绩效则是取决于服务的稳定性,业务迭代通常会影响服务可靠性问题,因为大部分的线上问题都是因为上线新版本导致的,这就导致两个业务研发与 SRE 团队产生冲突:是应该多上线还是少上线?
为了解决这个冲突提出了错误预算的概念。错误预算可以理解为余额,比如整个流程可以是:
1、产品管理层拍定这个月的服务可用性 SLO,比如 99.9%,那么错误预算为 0.1%
2、通过监控系统得出服务实际可用性,比如 99.95%
3、如果实际可用性 > SLO,那么就说明还有错误预算,可以发布新版本
—— P31 使用错误预估的目的
- 监控
- 监控报警
- 紧急事务处理
- 资源
- 容量规划与管理
基础概念
如果不详细了解服务各种行为的重要性,并且不去度量这些行为的正确性的话,就无法正确运维这个系统,更不要说可靠得运维了。所以,不管是对外服务,还是内部 API,我们都需要制定一个针对用户的服务质量指标,并且努力去达到这个服务目标。
—— P34 第四章 服务质量目标
- SLI:Service Level Indicator 服务质量指标,一个具体的量化指标
- 请求延迟
- 平均
- PCT50
- PCT95
- PCT99
- 错误率
- QPS
- 资源(CPU、内存、磁盘
- 利用率 吞吐量
- 可用性 = 机器正常运行时间 / 总时间 or 成功数 / 总请求数
PCT99:将一组数字从小到大排序,第 99% 位置的值为 PCT99。
PCT99 的意义在于,一个服务有的请求可能很快,有的请求很慢,直接取平均值可能掩盖长尾延迟。在实际开发中,QPS 越高,通常延迟也会越大,比如对于一个服务来说晚上是请求高峰量,其他时间都是低峰,导致取平均得到的值比较低
实际案例:
接口QPS
接口PCT99
- SLO:Service Level Objective,服务质量目标,SLI 的目标值
- 可用性高于 99%
- 平均延迟低于 100ms
SLO 的制定
- SLO 的制定与业务相关
- 不应该是 100% a. 从理论上来讲不可能 b. 对于用户来说 99.99 和 100 从体验上感知不到明显区别
Avaliability level Allowed unavailability window | ||||||
---|---|---|---|---|---|---|
per year | per quarter | per month | per week | per day | per hour | |
90% | 36.5 days | 9 days | 3 days | 16.8 hours | 2.4 hours | 6 minutes |
95% | 18.25 days | 4.5 days | 1.5 days | 8.4 hours | 1.2 hours | 3 minutes |
99% | 3.65 days | 21.6 hours | 7.2 hours | 1.68 hours | 14.4 minutes | 36 seconds |
99.5% | 1.83 days | 10.8 hours | 3.6 hours | 50.4 minutes | 7.20 minutes | 18 seconds |
99.9% | 8.76 hours | 2.16 hours | 43.2 hours | 10.1 minutes | 1.44 minutes | 3.6 seconds |
99.95% | 4.38 hours | 1.08 hours | 21.6 hours | 5.04 minutes | 43.2 minutes | 1.8 seconds |
99.99% | 52.6 minutes | 12.96 minutes | 4.32 minutes | 60.5 seconds | 8.64 minutes | 0.36 seconds |
99.999% | 5.26 minutes | 1.30 minutes | 25.9 minutes | 6.05 seconds | 0.87 seconds | 0.04 seconds |
- 该值应该是去努力达到的,不会超过太多,制定得太低无意义,制定太高浪费机器资源
- SLA:Service Level Agreement,服务质量协议,服务用户之间制定的协议,描述达到或者不达到 SLO 的后果(与业务相关)
监控
实现
收集、处理、汇总,并且显示关于某个系统的实时量化数据。
以 opentsdb 为例子,具体内容为:时间序列数据(time-series)+ 标签(tags)
举个例子,打点名字为 app.home.page,时间区间为 2020.11.12 00:00:00 ~ 2020.11.12 16:00:00,查询得到的结果为
{
dps: {
"1605110400": 1.1,
"1605110430": 1.9,
"1605110460": 1.0,
"1605110490": 1.3,
"1605110520": 1.4,
...
},
"tags": {
"method": "home"
...
}
}
意义
- 分析未来长期趋势,比如数据库容量问题
- 数据比较,上线后延迟、错误率是否变高了
- 报警,设置合理的报警,降低误报率。
报警
定义:在报警时间窗口(报警运行频率)内对监控数据进行计算,得出结果为 true / false。
报警规则规范:
- 在真正关心的地方设置正确阈值的报警。报警阈值过低报警无意义,过高则会降低对报警的敏感度,忽略真正的报警情况。
- 报警应该是可操作,收到报警后立即进行某种操作。如果是机械化的操作应该做成自动化流水线。
- 重复报警进行聚合。
相关链接
opentsdb doc:opentsdb.net/docs/build/…
作者:蔡裕鹏