通常我们使用云服务的时候, 服务提供商会提供 SLA(Service Level Aggrement),作为他们提供的服务质量的标准(常说的几个9),达不到会进行赔偿. 比如 AWS 的计算类服务: https://aws.amazon.com/compute/sla/ .
对公司自己 host 的 service, 我们内部也需要一些技术指标来 track 我们为客户提供的服务质量如何, 这个叫做 SLO(Service Level Objective). 也可以把他当成一个对内的,没有赔偿协议的SLA.
定义指标
我主要 track 两个指标:
- Availability (服务的可用性)
- Quality (服务质量)
Availability 的定义, 以前用简单的 service uptime 来定义, 在集群外部用一个 service check 定时 ping 我们 service 的 check endpoint, 失败就定义为 failure.
但这样的做法很粗糙, 和实际用户体验到的 service quality 相差比较大, 比如部署了新的代码,bug 导致某个很常用的 api 持续性抛 500. 此时我们的 service check 还是 up, 但用户就觉得你服务器挂了.
现在我用失败的 request 的个数来定义我们的 availability. 公式: 100 * ((total_reqs - failed_reqs) / total_reqs)
, 得到一个数值 eg: 99.9%, 99.99% …
access log 里 status code >= 500 的请求就当成失败, 并不完全准确(比如改了参数校验逻辑, 对正常的请求也抛了400), 但一般也够用了.
有时候 server 端需要进行一些大 change 的时候, 可能需要停机(maintenance window), 停机时候发生的错误,我也会算到 error 中去, 毕竟对用户来说和宕机没区别. 要尽量实现不停机的变更.
Quality 用 service 的 latency 来定义, 以前用的是一段时间内的平均 latency, 现在换成 P95 latency, 能更好得反应用户的实际体验.
P95 latency 的算法: 将一段时间内的所有 request 的 latency 值从小到大排序,
去掉最高的 5% request, 剩下的最高的那个值就是 P95 latency.
目前的 latency 是从 loadbalancer 的 log 里算的, 最准确的值其实应该从客户端/浏览器处统计.
Error budget
对于 availability, 我们还能计算当月的 error budget, 表示这个月接口还能抛多少次 5xx 错误: total * (1- availability)
.
假如一个月的请求总次数是 100M
, availability 是 99.99%, 算到 error budget 为 100*10^6 * ( 1-0.9999) = 10000
, 1万次.
针对 error budget 可以设置报警, 比如当 30%, 50%, 80% 的 budget 被用完后发送报警, 这时候就应该人工介入.
这里的 total 数目,一般用上月的值来预测,根据该 service 的每月 request 增减情况做适当调整.
当 error budget 接近耗完了,做操作和上线代码就要慎重了, 应该先把之前造成 error 的原因排查清楚再继续.
SLO policy 的变更与 review
SLO 的指标定义和阈值可能会变化, 目前我定的 review 周期是 1 个月,会在每月初统计上个月的情况, 视情况调整阈值.
当 SLO 的指标定义有变化, 要把具体算法的变动写到当月的 review doc 中.