3. SLO台账设计原则:SLO定义与目标、SLI指标选取、台账数据结构设计
SLO台账是质量门禁体系的核心数据底座,它承载了从SLI原始指标到SLO合规状态的全量映射关系。设计台账时,必须遵循可量化、可追溯、可验证三大原则,确保每条SLO都能与Jaeger链路中的具体Span、标签、持续时间建立一一对应关系。
3.1 SLO定义与目标:从业务价值到技术指标
SLO(Service Level Objective)是服务等级目标,它回答了“这个服务在多长时间内、以多高的成功率、处理多少请求才算健康”。定义SLO时,必须遵循SMART原则:
- S(Specific):目标具体,例如“99.9%的请求延迟低于200ms”。
- M(Measurable):可测量,依赖Jaeger等工具采集真实数据。
- A(Achievable):可达,基于历史基线设定,而非凭空臆想。
- R(Relevant):相关,直接关联用户体验或业务KPI。
- T(Time-bound):有时限,定义评估窗口(如过去30天滚动窗口)。
| SLO层级 | 定义目标 | 典型示例 | Jaeger关联字段 |
|---|---|---|---|
| L1 核心SLO | 直接影响用户感知,违约即触发P0告警 | 下单接口P99延迟 ≤ 500ms | span.duration、http.status_code |
| L2 重要SLO | 影响系统效率,违约触发P1告警 | 商品列表页错误率 ≤ 0.1% | span.error、http.method |
| L3 参考SLO | 反映系统容量趋势,用于容量规划 | 搜索服务吞吐量 ≥ 5000 QPS | span.count、service.name |
3.2 SLI指标选取:延迟、错误率、吞吐量
SLI(Service Level Indicator)是SLO的量化基石。在微服务可观测性体系中,黄金三角指标(延迟、错误率、吞吐量)是最通用且最有效的SLI集合。每个指标在Jaeger中都有明确的采集锚点。
3.2.1 延迟(Latency)
延迟衡量服务响应速度。选取延迟作为SLI时,必须明确百分位和统计窗口。
- P50(中位数):反映大多数用户的体验。
- P99(99分位):反映长尾延迟,是SLO的常用基准。
- P999(99.9分位):用于核心链路,容忍度极低。
Jaeger中通过span.duration字段直接获取,结合RED指标(Rate、Errors、Duration)进行聚合。
3.2.2 错误率(Error Rate)
错误率衡量请求失败的比例。定义错误率时,必须区分显式错误和隐式错误。
- 显式错误:HTTP 5xx、gRPC 状态码非OK、业务异常抛出。
- 隐式错误:HTTP 200但响应体包含错误码、超时但未返回错误码。
Jaeger中通过span.error=true标签标记显式错误,隐式错误需通过自定义标签(如business.error_code)补充。
3.2.3 吞吐量(Throughput)
吞吐量衡量服务处理请求的速率。通常以QPS(每秒请求数)或RPS(每秒请求数)为单位。
- 峰值吞吐量:用于评估系统容量上限。
- 基线吞吐量:用于判断流量异常下降(可能表示服务不可用)。
Jaeger中通过统计span.start_time在单位时间内的计数来推算吞吐量。
3.3 台账数据结构设计:可扩展、可查询、可验证
SLO台账的数据结构必须支持多维度查询(按服务、按时间、按合规状态)和自动化验证(门禁引擎直接读取)。推荐采用宽表+标签的设计模式,核心字段分为四类:
| 字段类别 | 字段名称 | 数据类型 | 说明 | 示例值 |
|---|---|---|---|---|
| 标识字段 | slo_id |
UUID | 全局唯一SLO标识 | slo-2025-001 |
service_name |
String | 所属微服务名称 | order-service |
|
slo_level |
Enum | L1/L2/L3 | L1 |
|
| 指标字段 | sli_type |
Enum | 延迟/错误率/吞吐量 | latency |
sli_percentile |
String | 百分位(延迟专用) | p99 |
|
sli_threshold |
Float | SLI阈值 | 500.0 (ms) |
|
slo_target |
Float | SLO目标合规率 | 99.9 (%) |
|
| 窗口字段 | window_type |
Enum | 滚动窗口/固定窗口 | rolling |
window_duration |
Int | 窗口时长(天) | 30 |
|
evaluation_interval |
Int | 评估间隔(分钟) | 5 |
|
| 状态字段 | current_compliance |
Float | 当前合规率 | 99.95 |
status |
Enum | 合规/警告/违约 | compliant |
|
last_updated |
Timestamp | 最后更新时间 | 2025-03-15T10:30:00Z |
sli_percentile字段区分不同百分位,避免为P50/P99/P999创建多个SLO条目。门禁引擎通过status字段快速过滤违约SLO,无需实时计算。
3.4 台账与Jaeger的集成验证链路
台账数据必须与Jaeger链路数据形成闭环验证。验证流程如下:
- 数据采集:Jaeger Collector接收Span,提取
span.duration、span.error、http.status_code等原始指标。 - 指标聚合:通过Spark/Flink作业,按
service_name和sli_type聚合为SLI指标值。 - 台账更新:将聚合结果写入SLO台账的
current_compliance字段,并计算status。 - 门禁触发:质量门禁引擎读取台账中
status=violated的条目,阻断对应服务的发布流程。 - 链路回溯:通过
slo_id关联Jaeger Trace,定位具体故障Span。
3.5 台账数据持久化与查询优化
推荐使用时序数据库(如InfluxDB、TimescaleDB)存储台账的current_compliance历史变化,使用关系型数据库(如PostgreSQL)存储台账的元数据定义。查询优化策略如下:
- 复合索引:在
(service_name, slo_level, status)上建立复合索引,加速门禁引擎的过滤查询。 - TTL策略:历史合规数据保留90天,元数据定义永久保留。
- 缓存层:使用Redis缓存
status=violated的活跃SLO列表,减少数据库压力。
-- PostgreSQL 台账元数据表DDL示例
CREATE TABLE slo_metadata (
slo_id UUID PRIMARY KEY,
service_name VARCHAR(128) NOT NULL,
slo_level VARCHAR(4) CHECK (slo_level IN ('L1', 'L2', 'L3')),
sli_type VARCHAR(20) CHECK (sli_type IN ('latency', 'error_rate', 'throughput')),
sli_percentile VARCHAR(8),
sli_threshold FLOAT NOT NULL,
slo_target FLOAT NOT NULL,
window_type VARCHAR(10) CHECK (window_type IN ('rolling', 'fixed')),
window_duration INT NOT NULL,
evaluation_interval INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 复合索引
CREATE INDEX idx_slo_status ON slo_metadata (service_name, slo_level, status);
status字段不要依赖实时计算,而是通过定时任务(每5分钟)从时序数据库拉取聚合结果后批量更新。门禁引擎只读取最终状态,确保决策延迟在秒级以内。