0%

浅谈 SRE & 业务监控

还记得两年之前青涩的我第一次面试 SRE 职位结束,面试官说还有什么想问的。我弱弱的问道:如何度量一个系统的稳定性或高可用能力呢? 面试官笑了一下,说你有没有听过“3 个 9”或“4 个 9”呢..

这篇文章将简单分享我对 SRE 的理解,同时结合个人与监控的故事,谈谈如何使用 SLI/SLO 进行业务监控的最佳实践~

我心中的 SRE

🤔 首先什么是 SRE(Site Reliability Engineering)?

  • 过程目标: 从字面不难理解,即通过软件工程 (Engineering) 来解决日益复杂的线上稳定性问题(Site Reliability)。
  • 结果目标: 「线上复杂度」增长与「运维人数」的扩张不成线性增长

感兴趣可以阅读 《Site Reliability Engineering》by Google or 直接阅读 我的读书笔记

DevOps 和 SRE 的关系

身为一名 SRE 快三年,一直对 DevOps 这个概念充满困惑。今天终于得到了解答,也趁此机会分享一下~

先从传统的协作模式说起: 开发编写业务代码,运维负责生产环节的稳定运行,但问题在于:开发不知道他们的代码如何被部署;而代码中业务逻辑对运维来说也完全是一个黑盒。 

而这两边的隔阂与信息不对称,很容易将双方的矛盾点不断放大:faster feature VS production reliability:

  1. 运维人员(Dev)关注线上的稳定性:如果出现生产可用性故障,需要半夜凌晨起来处理告警(大概率研发代码的缺陷)
  2. 研发同学(Ops)关心如何快速在生产环境交付代码:如果新的特性没有及时发布,他们也会有麻烦。

在这个背景下 DevOps 应运而生,期望通过「研发」与「运维」更加紧密的合作,来解决以上紧张的矛盾。而 SRE 则可以简单理解 DevOps 理念或指导思想的 最佳实践class SRE implements DevOps😄)。

监控相关名词解释

SLIs drive SLOs, which inform SLAs

  1. SLIs(Service Level Indicator): 明确判断当前服务是否可用的监控指标。注意尽量从 用户视角 定义 SLIs,例如 cpu/load 虽然很好理解,但用户不关心你的服务器是几核的,有多少内存,他们只在乎暴露的支付或转账服务是否可用。
  2. SLOs(Service Level Object): 基于 SLAs 的可量化目标,例如 99.95% 的用户请求在未来一周,都能在 200ms 内返回预期结果。
    • 虽然生产安全高于一切,但注意过分追求 100% 的 SLO 是个错误的目标,因为这很难,同时用户网络设备运营商,以及机房依赖的基础设施的可用率本身存在瓶颈。
  3. SLAs(Service Level Agreement): 更多的是 商业上的书面约定,破线需要赔付约定的金额,所以通常 SLO 会 SLA 设置的更加严格,保证提前预警。
  4. error budget: 不可用时间 / 整体时间,例如一年 99.99% 的 SLO,就代表你拥有 52min 的不可用时间,用来最大化的发布新的 feature(戴着手铐跳舞)

我和监控的故事

在蚂蚁,针对所有的核心线上业务,都制定一套非常完善的 故障等级定义机制(P1-P4):例如当「苹果代扣业务」当前分钟成功量与上一分钟环比下跌超过 20%,即会触发一条 P2 等级的告警;当持续 5 分钟都未恢复,将开启电话外呼。

用户的交易支付数据确实存在惊人的周期性,但同时也包含 很强的业务属性:例如活动秒杀之冲高回落,下游外部同步依赖异常,以及小流量业务的频繁抖动等等。成功量下跌的静态阈值确实有效,但同时也导致了大量误报告警。

1)本质问题 & 理想中的监控

当前分钟与上一分钟的成功量,环比下跌超过 30%

但三年过去了,回过头来看告警泛滥背后本质的问题在于:故障等级定义规则被大家误作为 SLI,因为成功量下跌 30% 与支付服务不可用不是充分条件(前置条件:因支付宝自身的技术问题导致)。而在这个不合理的 SLI 之上,我们利用人工智能算法和专家经验规则,来各种 workaround 降噪,自然无法根治监控这一顽疾。

如果从头开始做监控,应该简单 follow 以下两个步骤:

  1. 重新定义清楚面向用户或商户的 SLI:明确判断每笔流量是否因为技术原因导致不可用。
  2. 定义 SLO 后,利用 error budget 动态控制变更频率。甚至当一个周期内,某个业务服务的 error budget 耗尽,SRE 有权中止和拒绝任何线上变更。

2)回到现实

先回顾过去两年,我参与的几个项目:

  1. 告警智能降噪:通过机器学习的基线拟合与异常监测算法,代替人的经验自动判断时序数据是否异常,最终对告警进行降噪抑制。
  2. 单笔全风险:将多个应用的业务日志,通过 trace 关联后建模,通过代码编写对每一笔流量的「可用性」与「正确性」进行判断,例如:
    • 可用性:某个业务的支付请求,在入口网关返回给用户未知结果,同时在收单出现预期外的系统异常;巧的是异常对应机器在五分钟前进行了代码 beta 发布部署,则立即预警并阻断并回滚变更
    • 正确性:商户发起一笔代扣,由于支付宝访问渠道超时,返回未知结果(U)。需要覆盖时效性规则:商户对同笔订单是否在一个小时内发起查询并成功获取终态。否则会造成单边帐:商户侧订单状态与支付宝的状态不一致(U<->S/F),影响用户体验甚至客诉。
  3. 多维指标联合告警:结合多个时序监控的指标获取结论。例如入口成功量下跌超过 30%,自动检查来源数据是否下跌,或出口依赖的渠道是否异常等,断言内部服务是否正常。

因为现实中因为各种技术或资源的限制,我们很难一步配置理想(非黑即白)的 SLI,所以从上往下,随着数据的压缩以及资源的节省,我们可以在不同阶段做不同的事(本质都在寻找业务背后的 SLI):

  1. Logging
  2. Tracing
    • 单笔全风险
  3. Metrics
    • 单指标
    • 多指标联合告警
  4. Alarm
    • 告警智能降噪

The End

关于监控发现的分享到此为止了,因为历史包袱或资源的限制下,我们很难去定义完美的 SLI,但我们可以像计算机缓存结构一样,分层地去解决问题。期望未来有一天可以对监控发现有一个更加体系化的解法。

最后分享一下灰度这个概念的有趣故事(国外又称为金丝雀Canary):很久以前英国的煤矿工人下矿井的时候,为了防止中毒,会待一只对瓦斯十分敏感的金丝雀,如果它有异常这说明瓦斯浓度过高,需要撤离,达到提前预警的作用 XD

参考

  1. https://wu-sheng.github.io/me/articles/metrics-tracing-and-logging.html