如何构建服务等级体系?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)启动步骤 

  ① 安装kubectlhttps://kubernetes.io/docs/tasks/tools/install-kubectl-windows/#install-kubectl-binary-on-windows-via-direct-download-or-curl

  • 下载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 .
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

 

posted @ 2025-11-24 16:04  筱倩  阅读(1)  评论(0)    收藏  举报