如何构建服务等级体系?SLI/SLO/SLA与VALET框架指南
一、相关定义
1、SLI、SLO、SLA是什么
SLI:Service Level Indicator,是服务等级指标的简称,她是衡量系统稳定性的指标。
SLO:Service Level Objective,服务等级目标的简称,也是我们设定的稳定性目标。
SLA:服务等级协议,假如是给第三方做的网站,并签订了协议SLO达不到99.999%就赔偿多少钱,那么根据计算出的SLO,再根据签订的SLA协议,算出补偿的金额。
2、如何选择SLI
在系统中,常见指标有以下几种:
- 系统层面:CPU使用率、内存使用率、磁盘使用率等
- 应用服务器层面:端口存活状态、JVM的状态等
- 应用运行层面:状态码、时延、QPS、TPS以及连接数等
- PASS层面:mysql、redis、kafka、mq和分布式文件储存等组件的QPS、TPS、时延等。
那我们选取指标只需要遵循两个原则:1)选择能标识一个主体是否稳定的目标。2)优先选择与用户体验强相关或用户可以明显感知的指标。
我们可以直接套用Google的方法:VALET(Volume容量/流量、Availability可用性、Latency延迟、Error错误、Ticket故障单)。这是Google提出的服务等级指标选择框架,通过5个核心维度帮技术团队系统性地衡量服务稳定性,未设定服务等级目标提供清晰的指标体系。
(1)Volumn容量/流量
核心含义:衡量服务地承载能力或业务规模,即服务在单位时间内可处理的最大请求量或数据量。
关键指标:
- 在线服务:QPS(每秒查询量)、TPS(每秒事务量)、并发连接数、会话数等。
- 数据平台:任务吞吐量(每小时处理记录数/任务数)
应用场景:日常运维时设定常规流量下的容量基线(如日常QPS不低于1000);大促/峰值场景,针对双11等流量高峰,指定扩容后的容量目标(如大促期间QPS峰值不低于5000)
(1)QPS,每秒查询量
能衡量系统处理简单请求的速度(比如打开网页、搜索商品等),数字越大说明系统响应快,能同时相应更多小请求。
(2)TPS,每秒事务量
QPS是但此请求,TPS一整套完整操作(如从选餐到结账的全流程)。作用是衡量系统“处理复杂业务”的能力,数字越大,说明系统能同时搞定更多复杂业务。
(3)并发连接数
衡量系统“同时维持多少个活跃用户”的能力(比如1000个用户同时打开APP但没操作,也算连接中)。
(4)会话数
衡量系统同时处理多少个独立用户会话的能力(如登录APP后,系统会生成一个会话ID,只要没退出,这个会话就持续存在)
(2)Availability可用性
核心含义:衡量服务的正常运行状态,即服务成功响应请求比例。
关键指标:
- 在线服务:请求成功率(非5xx状态码占比)、接口调用成功率等。
- 数据平台:任务执行成功率(如ETL任务成功完成的比例)
应用场景:直接关联用户体验,如99.99%的请求返回非5xx状态码(即四个九可用性目标);业务连续性保障,通过监控可用性,及时发现服务中断或降级问题。
(3)Latency延迟
核心含义:衡量服务的响应速度,即请求从发出到收到响应的时间,直接影响用户体验。
关键指标:
- 在线服务:P90/P95/P99时延(如90%的请求时延<=80ms)、平均响应时间(需结合分布式分析)。
Pxx时延:xx%的用户等待时间不超过这个数——它比平均值更真实地反映用户的最坏体验,是商家/平台优化服务的核心指标。 比如,你点奶茶时商家说“平均15分钟取餐”,但实际P80是20分钟——这意味着你有90%的概率在20分钟内拿到,只有10%的概率等更久,比平均15分钟更让你心里有数。 举例:假设某外卖平台一天有1000个订单,配送时间从10分钟到60分钟不等,把这些时间从小到大排序后: (1)P90时延=-35分钟:排在第900位(1000*90%)的订单配送时间<=35分钟 (2)P95时延=45分钟:95%的订单配送时间<=45分钟 (3)P99时延=55分钟:99%的订单配送时间<=55分钟
应用场景:避免平均时延陷阱,由于时延发呢不呈正态分布(少数请求可能极快或极慢),通常用分位数而非平均值来设定目标,更准确反应用户真实体验。
(4)Errors错误
核心含义:衡量服务的错误发生频率,包括系统错误和业务逻辑错误。
关键指标:
- 系统错误:5xx状态码占比(服务器内部错误)
- 业务错误:4xx状态码占比(如404、401等客户端错误)、自定义业务错误码(如商品库存不足)
应用场景:系统错误需优先修复,业务错误需结合产品逻辑优化;设定容错目标,例如5xx错误率<=0.005%。
(5)工单(Tickets)
核心含义:衡量服务的自动化程度,即服务异常时需要人工介入的频率,反映系统的自愈能力。
关键指标:
- 人工处理的故障单数量
- 需人工恢复的任务/请求占比
应用场景:
- 运维效率优化:减少人工介入意味着系统更稳定、自动化程度更高。
- 资源分配:若故障单激增,需排查系统薄弱环节(如监控缺失、告警规则不合理)。
二、开源方案学习
1、开源方案1:https://github.com/google/prometheus-slo-burn-example
(1)项目各模块
- Server:模拟服务会产生一定比例的服务响应
- Prometheus:
![image]()
- Grafana组件:
![image]()
- CloudPorber组件:负责主动探测服务健康状况
![image]()
- Kubernetes部署配置
![image]()
(2)启动步骤
- 下载cubectl.exe。
- 在VSCode终端用kubectl version --client验证是否安装成功。
- 在运行kubectl apply -f ./k8s前,需要先启动一个本地Kubernetes集群:在Docker destop中打开设置,转到Kubernetes选项,勾选Enable Kubernetes,点击apply & restart。
- 上面做好之后,在终端输入kubectl cluster-info、kubectl get nodes,若这些命令成功返回信息,说明k8集群正在运行,然后继续执行kubectl apply -f ./k8s。
- kubectl cluster-info:是Kubernetes的一个诊断命令,用于显示集群中控制平面和核心组件的连接信息。
- 这个显示结果:表明Kubernetes屏幕(即主节点组件)正在运行,API服务地址是https://kubernetes.docker.internal:6443,这个地址是Docker Desktop特有的。CoreDNS is running at,这表明集群的DNS服务CoreDNS正在运行,他是Kubernetes集群内部服务发现的关键组件。
- 表示有一个名为docker-desktop的节点,状态是ready,扮演控制平面节点。
- 出现问题:extensions/v1beta1 和 apps/v1beta1 这些API版本在较新的Kubernetes版本中已经被弃用或移除。您的Kubernetes版本是v1.34.1,这是一个相对较新的版本,不再支持这些旧的API版本。
② 本地启动服务 & Docker启动服务
- 构建Server镜像:进入server目录并构建镜像
cd server docker build -t slo-server .
- 运行Server容器。启动后可以通过http://localhost:8080来测试服务
docker run -p 8080:8080 slo-server
- 测试服务端点:服务提供了几个有用的端点。
- GET /:主页,随机返回200或500状态码
- GET /errors:查看当前错误率
- GET /errors/{percent}:设置新的错误率
- GET /metrics:普罗米修斯指标端点
- GET /healthz:健康检查端点
curl http://localhost:8080/ curl http://localhost:8080/errors curl http://localhost:8080/errors/5.5
- 其他组件Docker化:
- 普罗米修斯:用于监控和收集指标
- Grafana:用于可视化指标
- Cloudprober:用于探测服务
【ps】若想一次性启动所有服务,可以查找项目根目录是否有docker-compose.yml文件,若有则可以直接docker-compose up。这将同时启动所有相关服务,并自动配置它们之间的网络连接。这种方式比完整的 Kubernetes 部署更轻量,适合开发和测试用途。
2、开源方案2:https://github.com/slok/sloth?tab=readme-ov-file
编写一个simple-example.yaml。
version: "prometheus/v1" service: "myservice" labels: owner: "myteam" repo: "myorg/myservice" tier: "2" slos: # We allow failing (5xx and 429) 1 request every 1000 requests (99.9%). - name: "requests-availability" objective: 99.9 description: "Common SLO based on availability for HTTP request responses." sli: events: error_query: sum(rate(http_request_duration_seconds_count{job="myservice",code=~"(5..|429)"}[{{.window}}])) total_query: sum(rate(http_request_duration_seconds_count{job="myservice"}[{{.window}}])) alerting: name: MyServiceHighErrorRate labels: category: "availability" annotations: # Overwrite default Sloth SLO alert summmary on ticket and page alerts. summary: "High error rate on 'myservice' requests responses" page_alert: labels: severity: pageteam routing_key: myteam ticket_alert: labels: severity: "slack" slack_channel: "#alerts-myteam"
这是Sloth的SLO定义文件,用来描述我们想要为服务设置的可靠性目标。
- 服务名为 "myservice"
- 目标是 99.9% 的可用性
- 错误请求定义为 HTTP 状态码为 5xx 或 429 的请求
- 配置了页面告警(发送给 "pageteam")和工单告警(发送到 Slack 的 "#alerts-myteam" 频道)
go run cmd/sloth/main.go generate -i simple-example.yaml。这样就可以生成完整的 Prometheus 规则集,包括 SLI 记录规则、SLO 元数据规则和多窗口多燃烧率告警规则。
参考:
1、 https://www.51cto.com/article/674806.html
2、https://github.com/google/prometheus-slo-burn-example
3、https://github.com/slok/sloth?tab=readme-ov-file




浙公网安备 33010602011771号