跳转至

SRE、安全、数据与平台实操

为一个 HTTP 服务建立 SLI、燃烧率告警与 OpenTelemetry 采集链路

任务

给定一个暴露 /api/orders/{id} 的 HTTP 服务、Prometheus1 和两个 OTel Collector2 实例。要求规范化路由指标,定义 28 天 99.9% 成功率 SLO3,写出可测试的 PromQL4/告警思路;配置 Collector 在后端中断时不拖垮业务,对设计容量内完整到达采样器的错误 trace/span5 设 100% 采样目标、抽样正常 trace,并说明如何检测上游缺 span、队列溢出和导出丢弃。

相关技术说明

SLI 必须以有效业务请求为分母,健康检查、明显客户端参数错误是否排除要写清。燃烧率6使用与 SLO 同一分子/分母,并以长短窗共同判断。Collector 的 memory_limiter 应靠前、batch 靠后,尾采样前需按 trace ID 一致路由;队列有界,应用用异步导出。高基数订单 ID 不进入 metrics label,而放 trace/log 属性并做敏感字段控制。

“错误 trace 100%”只能描述对已完整到达 tail sampler 的采样策略,不能承诺端到端零丢失:SDK/agent 先丢 span、trace 未完整路由、队列溢出或 Collector/后端故障都可能留下缺口。实现需给接收、拒绝、丢弃、不完整 trace 和导出失败定义指标/SLO,并明确过载时先丢正常 trace、同时保证业务线程不被遥测阻塞。

参考实现思路/命令

假设健康检查已由采集规则排除、4xx 客户端错误不计入有效事件、5xx 为坏事件,先直接计算 burn rate;错误预算比例为 0.001

(
  sum(rate(http_server_request_duration_seconds_count{service_name="orders",http_route="/api/orders/{id}",http_response_status_code=~"5.."}[5m]))
  /
  clamp_min(sum(rate(http_server_request_duration_seconds_count{service_name="orders",http_route="/api/orders/{id}",http_response_status_code!~"4.."}[5m])), 1e-9)
) / 0.001

成功率是 1 - 坏事件率。若某类 4xx 也代表服务业务失败,应把它加入坏事件并保留在分母;若 2xx 中存在业务失败,则应改用业务结果指标,不能只看 HTTP code。分别计算 1h/5m 和 6h/30m 组合,并为低流量设最小事件数。用 promtool check rules rules.ymlpromtool test rules tests.yml 校验规则。Collector 配置至少包含 OTLP receiver、memory_limiter、资源属性规范、tail sampling(error/latency/probabilistic)、batch、有界 sending queue 和健康扩展;用 otelcol validate --config config.yaml(具体二进制参数按发行版核对)做静态校验。

实践经验

生产落地先让旧指标与新 OTel 指标双跑一周,按请求量、错误和路由对账,给数据源加标记,避免双计数。随后注入 500 错误、无流量、Collector 断网和 trace 后端限流:确认在设计峰值内,完整到达采样器的错误 trace 全被选择,正常 trace 可受控丢弃、业务延迟不升;超出容量时则必须让接收/拒绝/不完整/导出缺失独立报警,不能把搜索不到 trace 解释为没有错误。尾采样会增加内存与决策延迟,所以按峰值 spans/s 容量压测,而不是复制默认配置。

验收标准

  • SLI 口径、排除项、窗口和零/无数据语义写清,PromQL 标签匹配正确。
  • 至少一组长短窗 burn-rate 规则有测试样例、runbook 与 owner。
  • Collector 后端断开时队列有上限、核心信号有优先级且业务不被阻塞,任何 trace 缺口可量化。
  • 仪表盘能从 SLO 指标经 exemplar/trace ID 跳到 trace 与日志。

评分(100 分)

  • SLI/SLO 与 PromQL 正确性 30 分;告警与测试 25 分。
  • Collector 可靠性、采样和容量 25 分;验证/安全/成本边界 20 分。

常见错误

  • 把 5xx 数量直接当错误率,分子分母标签不一致。
  • 使用原始 URL/订单号作指标标签,或用 or vector(0) 掩盖采集失败。
  • Collector 无 memory limiter/有界队列,尾采样实例又未做 trace 一致路由。

构建可验证的容器供应链:SBOM、签名、Provenance 与准入

任务

为一个容器应用设计并演示从受保护 commit 构建到 Kubernetes 部署的验证链。要求最终镜像按 digest 引用,生成 SBOM7 和 provenance8,以 CI 的短期身份签名,并写出准入策略的判定条件;还要给出伪造签名、未知 builder 和紧急回滚的测试方案。

相关技术说明

SBOM 说明组件,provenance 说明构建来源,签名表达某身份对 digest 的声明,三者不可互相替代。keyless 流程的验证重点是 OIDC9 issuer、subject、受保护工作流和透明日志;KMS 流程则重点保护密钥与调用身份。门禁必须对实际 digest 验证,而不是仅检查 tag 或“存在任意签名”。SLSA10 采用要明确规范版本及满足的具体要求,不应自称模糊认证。

参考实现思路/命令

构建后解析不可变 digest,并用所选工具生成 SPDX/CycloneDX SBOM;示意命令如下,实际参数按当前官方版本固定:

docker buildx build --push -t registry.example/app:${GIT_SHA} .
crane digest registry.example/app:${GIT_SHA}
syft registry.example/app@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef -o spdx-json=sbom.spdx.json
cosign sign --yes registry.example/app@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
cosign verify --certificate-identity-regexp '^https://github.com/acme/app/.github/workflows/release.yml@refs/' --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' registry.example/app@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

构建系统自动生成 in-toto/SLSA provenance,声明 source revision、builder ID、materials 和 subject digest;将 SBOM/provenance 作为 OCI 附件或受控证明保存。准入先 audit,再要求:digest 引用、允许 issuer/subject、指定 builder、source 为受保护仓库/分支且证明 subject 与镜像一致。CI 使用 OIDC 换取短期 registry/云权限,外部 PR 池无签名权限。

实践经验

生产落地先盘点历史运行 digest 并为可信回滚集合补齐证明,避免一强制就无法回滚。用测试仓库签名、篡改 tag、复制镜像、修改证明 subject 和让透明日志不可用等场景演练;策略必须拒绝错误身份,允许 digest 未变的合法复制,并按预定 fail 策略处理验证服务故障。紧急 break-glass 走受控构建、双人批准和自动到期,不允许个人笔记本直推。

验收标准

  • 运行镜像、SBOM、签名和 provenance 均绑定同一 digest,可回溯 commit/builder。
  • 未授权 subject 或未知 builder 的有效密码学签名仍会被拒绝。
  • 外部 PR 无生产凭证;发布会话可追溯 workflow run 与审批。
  • audit→enforce 迁移、历史制品和紧急回滚方案可执行。

评分(100 分)

  • 信任链与 digest 绑定 30 分;身份/Runner 隔离 20 分。
  • provenance/SBOM 质量 20 分;准入与负向测试 20 分;应急治理 10 分。

常见错误

  • 签可变 tag、只检查“有签名”,不限制 issuer/subject。
  • 在开发者机器生成 provenance,或把 SBOM 当漏洞扫描/来源证明。
  • 一步强制且没有历史回滚制品与验证服务故障策略。

完成 PostgreSQL 指定时间点恢复并提交恢复证据

任务

给定一份 base backup、连续 WAL 归档和事故时间线:10:17:30 发生误删,业务要求恢复到误删前且 RPO≤5 分钟、RTO≤60 分钟。候选人需在隔离环境恢复,证明目标点、验证关键表/权限/扩展,给出生产切换和旧库保留方案,并诊断一个人为制造的 WAL 缺段。

相关技术说明

PITR 依赖一致性基线和从该基线到目标点的连续 WAL。目标可按时间、LSN、事务 ID 或命名恢复点选择;时间存在时区和应用/数据库时钟偏差,关键变更前创建 named restore point 更稳。恢复到目标后必须提升生成新时间线,旧主需隔离。成功启动只证明物理可读,不证明业务完整、权限正确或外部副作用安全。

参考实现思路/命令

先校验备份 manifest/checksum 和 WAL 列表,在无生产网络出口的临时实例还原数据目录。配置 restore_command 从只读归档取 WAL,并设置类似 recovery_target_time = '2026-08-08 10:17:29+08'recovery_target_action = 'pause';具体文件位置和参数以目标 PostgreSQL 大版本官方文档为准。启动后查看日志确认重放到目标,执行:

SELECT pg_is_in_recovery(), pg_last_wal_replay_lsn(), now();
SELECT count(*), min(created_at), max(created_at) FROM critical_orders;
SELECT extname, extversion FROM pg_extension ORDER BY 1;

用业务审计表确认误删行仍在、10:17:30 后不应存在的写入未混入;比较分桶 checksum、序列/约束、角色权限并跑只读应用烟测。WAL 缺段时停止恢复、记录缺失 segment,检查归档/副本/对象版本;禁止用空文件或跳过日志伪造成功。

实践经验

生产切换前 fence 原库写入、记录最终业务水位,恢复库提升后通过代理小流量验证;误删后产生的合法业务写需要从事件日志补偿或人工对账,不能简单声称 PITR 自动合并。旧库和归档只读保留到对账完成。演练应记录下载、重放、验证每阶段耗时,暴露密钥、带宽和扩展依赖;为了避免恢复环境发短信/扣款,DNS 与外部凭证必须替换。

验收标准

  • 明确基线/WAL 连续性并恢复到正确时区和目标点,不绕过缺段。
  • 数据、业务不变量、权限、扩展和应用只读旅程均有证据。
  • 切换包含 fencing、连接路由、后续写补偿、回滚和旧库保留。
  • 报告实际 RPO/RTO、瓶颈与可复现实验步骤。

评分(100 分)

  • 恢复链与目标点正确 35 分;业务验证 25 分。
  • 切换/对账/安全隔离 25 分;证据和时间测量 15 分。

常见错误

  • 看到数据库启动就宣布恢复成功,未验证业务语义。
  • 忽略时区、WAL 缺段或旧主 fencing,造成错误恢复或双写。
  • 恢复环境使用生产凭证,意外触发真实外部副作用。

排查 Kafka Lag、修复重复消费并安全重放 DLQ

任务

给定一个 24 分区 topic、40 个消费者、持续上涨的 lag、频繁 rebalance 日志和包含 5 万条消息的 DLQ。要求定位瓶颈,提出止血配置/代码修改,安全重放一小批消息,并证明没有重复业务副作用;禁止直接跳 offset 或清空 DLQ。

相关技术说明

实例多于分区不会提高 group 并行度。必须区分生产速率、净消费速率、按分区 lag、最老年龄、poll 处理时间和下游限制。offset 是消费进度而非业务完成证明;处理完成后提交会允许重复,处理前提交会造成丢处理。DLQ 重放需修复根因、稳定业务幂等键、保留原始上下文和限速,不能把异常流量再次打垮下游。

参考实现思路/命令

用当前发行版自带 consumer group 工具查看每分区 current/log-end offset 与成员分配,例如:

kafka-consumer-groups.sh --bootstrap-server broker:9092 --describe --group notifications
kafka-consumer-groups.sh --bootstrap-server broker:9092 --describe --group notifications --state

把 broker/group 输出与应用的 poll latency、处理计时、rebalance、GC 和下游 429/5xx 对齐。若单一分区热点,增加实例无效;若处理超过 max.poll.interval.ms,优先减批、隔离慢调用或异步化,再按可证明上界调整间隔。业务库增加以 event ID 为键的 inbox/唯一约束,事务完成后才推进 offset。重放工具支持 --dry-run、过滤错误类别/时间、每秒上限、新 replay ID,并先 10 条、100 条、1% 扩大;比较业务不变量和去重命中。

实践经验

生产止血通常先暂停产生不可逆副作用的消费者,而不是停整个 broker;为健康消息保留通道,将可恢复失败转延迟重试。offset reset 仅在明确需要重放/跳过且保存原位置、审批和对账后使用。调整 poll 超时会延迟死实例检测,扩大并发会压垮下游,因此验收以净排空时间、重复副作用和下游 SLO 为准,而不是“lag 最终归零”。

验收标准

  • 能证明是 rebalance、分区倾斜、处理瓶颈或下游限制中的哪一类。
  • 修改后 group 稳定,净消费速率高于生产速率且排空时间可估。
  • DLQ 分阶段、限速、可暂停重放,重复事件被业务幂等拦截。
  • 保存原 offset、消息上下文和审计,错误场景可停止/回滚。

评分(100 分)

  • 证据链与根因 30 分;consumer/offset 语义 25 分。
  • 幂等与 DLQ 重放安全 30 分;容量、验证和沟通 15 分。

常见错误

  • 继续扩到超过分区数,或只看总 lag 不看最老年龄/分区。
  • 盲目加大超时、无限重试,未修复慢处理和下游背压。
  • 清空 DLQ、强行 reset offset,或只靠 Kafka producer 幂等保证外部副作用。


  1. Prometheus 是开源监控与告警系统,以带标签的时间序列保存指标。参见 Prometheus 官方文档。 

  2. OTel 是 OpenTelemetry 的简称;Collector 用于接收、处理和导出 traces、metrics 与 logs。参见 OpenTelemetry 官方文档。 

  3. SLI 是实际服务表现的量化指标,SLO 是该指标在给定窗口内应达到的目标。 

  4. PromQL 是 Prometheus Query Language,用于选择、计算和聚合 Prometheus 时间序列。 

  5. trace 表示一次请求的端到端调用链,span 表示链路中的单个操作。 

  6. 燃烧率表示错误预算的实际消耗速度相对于允许速度的倍数;大于 1 表示消耗过快。 

  7. SBOM 是 Software Bill of Materials(软件物料清单),列出制品包含的软件组件及版本。 

  8. provenance(来源证明)记录制品由什么源码、身份和构建过程生成。 

  9. OIDC 是 OpenID Connect,一种可让 CI 作业以可验证身份换取短期凭证的身份协议。 

  10. SLSA 是 Supply-chain Levels for Software Artifacts,一套逐级提高软件供应链完整性的规范框架。参见 SLSA 官方规范。