网站可靠性工程师 sre-engineer

专家级网站可靠性工程师,专注于SLOs、错误预算和可靠性工程实践。精通事故管理、事后分析、容量规划和构建可扩展、弹性系统,重点放在可靠性、可用性和性能上。

DevOps 0 次安装 0 次浏览 更新于 2/23/2026

name: sre-engineer description: “专家级网站可靠性工程师,专注于SLOs、错误预算和可靠性工程实践。精通事故管理、事后分析、容量规划和构建可扩展、弹性系统,重点放在可靠性、可用性和性能上。”

网站可靠性工程师

目的

提供专家级的网站可靠性工程专业知识,用于构建和维护高可用性、可扩展性和弹性系统。专注于SLOs、错误预算、事故管理、混沌工程、容量规划和可观测性平台,重点放在可靠性、可用性和性能上。

何时使用

  • 定义和实施SLOs(服务水平目标)和错误预算
  • 从检测到解决再到事后分析的事故管理
  • 构建高可用性架构(多区域、容错)
  • 进行混沌工程实验(故障注入、弹性测试)
  • 容量规划和自动扩展策略
  • 实施可观测性平台(指标、日志、追踪)
  • 设计减少劳作和自动化策略

快速开始

在以下情况下调用此技能:

  • 定义和实施SLOs(服务水平目标)和错误预算
  • 从检测到解决再到事后分析的事故管理
  • 构建高可用性架构(多区域、容错)
  • 进行混沌工程实验(故障注入、弹性测试)
  • 容量规划和自动扩展策略
  • 实施可观测性平台(指标、日志、追踪)

不要在以下情况下调用:

  • 仅需要DevOps自动化(CI/CD流水线使用devops-engineer)
  • 应用级调试(使用debugger技能)
  • 没有可靠性上下文的基础设施配置(使用cloud-architect)
  • 数据库性能调优(使用database-optimizer)
  • 安全事故响应(使用incident-responder进行安全)


核心工作流程

工作流程1: 定义和实施SLOs

**用例:**新微服务需要SLO定义和监控

步骤1: SLI(服务水平指标)选择

# 服务: 用户认证API
# 关键用户旅程: 登录流程

SLI候选:
1. 可用性(请求成功率):
   定义: (successful_requests / total_requests) * 100
   测量: HTTP 2xx响应与5xx错误
   理由: 服务健康的核心指标
   
2. 延迟(响应时间):
   定义: P99响应时间 < 500ms
   测量: 从请求接收到响应发送的时间
   理由: 用户体验直接受慢登录影响
   
3. 正确性(认证准确性):
   定义: 有效令牌发行/认证尝试
   测量: 发行后1小时内JWT验证失败
   理由: 安全性和功能正确性

SLO的选定SLIs:
- 可用性: 99.9%(主要SLO)
- 延迟P99: 500ms(次要SLO)

步骤2: SLO定义文档

# 认证服务SLO

## 服务概览
- **服务**: 用户认证API
- **所有者**: 平台团队
- **重要性**: Tier 1(阻止所有用户操作)

## SLO承诺

### 主要SLO: 可用性
- **目标**: 28天滚动窗口内99.9%可用性
- **错误预算**: 0.1% = 每28天40.3分钟停机时间
- **测量**: `(count(http_response_code=2xx) / count(http_requests)) >= 0.999`
- **排除**: 计划维护窗口,客户端错误(4xx)

### 次要SLO: 延迟
- **目标**: P99延迟 < 500ms
- **错误预算**: 1%的请求可以超过500ms
- **测量**: `histogram_quantile(0.99, http_request_duration_seconds) < 0.5`
- **测量窗口**: 5分钟滑动窗口

## 错误预算政策

### 预算剩余行动:
- **> 50%**: 正常开发速度,允许功能发布
- **25-50%**: 减缓功能发布,优先考虑可靠性
- **10-25%**: 功能冻结,专注于SLO改进
- **<10%**: 事故声明,全力以赴可靠性

### 预算耗尽(0%):
- 立即冻结功能
- 回滚最近更改
- 需要根本原因分析
- 需要执行通知

## 监控和警报

**Prometheus警报规则:**
```yaml
groups:
  - name: auth_service_slo
    interval: 30s
    rules:
      # 可用性SLO警报
      - alert: AuthServiceSLOBreach
        expr: |
          (
            sum(rate(http_requests_total{service="auth",code=~"2.."}[5m]))
            /
            sum(rate(http_requests_total{service="auth"}[5m]))
          ) < 0.999
        for: 5m
        labels:
          severity: critical
          service: auth
        annotations:
          summary: "认证服务可用性低于SLO"
          description: "当前可用性: {{ $value | humanizePercentage }}"
      
      # 错误预算快速消耗警报(快速消耗)
      - alert: AuthServiceErrorBudgetFastBurn
        expr: |
          (
            1 - (
              sum(rate(http_requests_total{service="auth",code=~"2.."}[1h]))
              /
              sum(rate(http_requests_total{service="auth"}[1h]))
            )
          ) > 14.4 * (1 - 0.999)  # 1小时内消耗2%的月度预算
        for: 5m
        labels:
          severity: critical
          service: auth
        annotations:
          summary: "认证服务以14.4倍速度消耗错误预算"
          description: "按此速度,月度预算将在2天内耗尽"
      
      # 延迟SLO警报
      - alert: AuthServiceLatencySLOBreach
        expr: |
          histogram_quantile(0.99,
            sum(rate(http_request_duration_seconds_bucket{service="auth"}[5m])) by (le)
          ) > 0.5
        for: 5m
        labels:
          severity: warning
          service: auth
        annotations:
          summary: "认证服务P99延迟超过SLO"
          description: "当前P99: {{ $value }}s (SLO: 0.5s)"

步骤3: Grafana仪表板

{
  "dashboard": {
    "title": "认证服务SLO仪表板",
    "panels": [
      {
        "title": "30天可用性SLO",
        "targets": [{
          "expr": "avg_over_time((sum(rate(http_requests_total{service=\"auth\",code=~\"2..\"}[5m])) / sum(rate(http_requests_total{service=\"auth\"}[5m])))[30d:5m])"
        }],
        "thresholds": [
          {"value": 0.999, "color": "green"},
          {"value": 0.995, "color": "yellow"},
          {"value": 0, "color": "red"}
        ]
      },
      {
        "title": "错误预算剩余",
        "targets": [{
          "expr": "1 - ((1 - avg_over_time((sum(rate(http_requests_total{service=\"auth\",code=~\"2..\"}[5m])) / sum(rate(http_requests_total{service=\"auth\"}[5m])))[30d:5m])) / (1 - 0.999))"
        }],
        "visualization": "gauge",
        "thresholds": [
          {"value": 0.5, "color": "green"},
          {"value": 0.25, "color": "yellow"},
          {"value": 0, "color": "red"}
        ]
      }
    ]
  }
}


工作流程3: 混沌工程实验

**用例:**验证对数据库故障转移的弹性

实验设计:

# chaos-experiment-db-failover.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: database-primary-kill
  namespace: chaos-testing
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: postgresql
      role: primary
  scheduler:
    cron: "@every 2h"  # 每2小时运行实验
  duration: "0s"  # 立即杀死

假设:

## 假设
**稳态**: 
- 应用程序保持99.9%可用性
- P99延迟 < 500ms
- 数据库查询成功,自动故障转移到副本

**干扰**:
- 杀死主数据库pod(模拟AZ故障)

**预期行为**:
- Kubernetes在10秒内检测到pod故障
- 副本在30秒内提升为主
- 应用程序在5秒内重新连接到新主
- 总影响:<45秒的提高错误率(<5%)
- 无数据丢失(同步复制)

**中止条件**:
- 错误率> 20%超过60秒
- 发出手动回滚命令
- 客户投诉激增>10倍正常

执行步骤:

#!/bin/bash
# chaos-experiment-runner.sh

set -e

echo "=== 混沌实验:数据库故障转移 ==="
echo "开始时间: $(date)"

# 第1步:基线指标(5分钟)
echo "[1/7] 收集基线指标..."
START_TIME=$(date -u +%s)
sleep 300

BASELINE_ERROR_RATE=$(promtool query instant \
  'sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))' \
  | jq -r '.data.result[0].value[1]')

echo "基线错误率: ${BASELINE_ERROR_RATE}"

# 第2步:注入故障
echo "[2/7] 注入故障:杀死主数据库pod..."
kubectl delete pod -l app=postgresql,role=primary -n production

# 第3步:监控故障转移
echo "[3/7] 监控故障转移过程..."
for i in {1..60}; do
  READY_PODS=$(kubectl get pods -l app=postgresql -n production \
    -o jsonpath='{.items[?(@.status.conditions[?(@.type=="Ready")].status=="True")].metadata.name}' \
    | wc -w)
  
  if [ $READY_PODS -ge 1 ]; then
    echo "故障转移完成于T+${i}s: $READY_PODS就绪pod"
    break
  fi
  
  echo "T+${i}s: 等待副本提升..."
  sleep 1
done

# 第4步:测量影响
echo "[4/7] 测量事件影响..."
sleep 60  # 等待指标稳定

INCIDENT_ERROR_RATE=$(promtool query instant \
  'max_over_time((sum(rate(http_requests_total{code=~"5.."}[1m])) / sum(rate(http_requests_total[1m])))[5m:])' \
  | jq -r '.data.result[0].value[1]')

echo "事件期间峰值错误率: ${INCIDENT_ERROR_RATE}"

# 第5步:验证恢复
echo "[5/7] 验证服务恢复..."
for i in {1..30}; do
  CURRENT_ERROR_RATE=$(promtool query instant \
    'sum(rate(http_requests_total{code=~"5.."}[1m])) / sum(rate(http_requests_total[1m]))' \
    | jq -r '.data.result[0].value[1]')
  
  if (( $(echo "$CURRENT_ERROR_RATE < 0.01" | bc -l) )); then
    echo "服务恢复于T+$((60+i))s"
    break
  fi
  
  sleep 1
done

# 第6步:数据完整性检查
echo "[6/7] 运行数据完整性检查..."
psql -h postgres-primary-service -U app -c "SELECT COUNT(*) FROM orders WHERE created_at > NOW() - INTERVAL '10 minutes';"

# 第7步:结果总结
echo "[7/7] 实验结果:"
echo "================================"
echo "基线错误率: ${BASELINE_ERROR_RATE}"
echo "峰值错误率: ${INCIDENT_ERROR_RATE}"
echo "当前错误率: ${CURRENT_ERROR_RATE}"
echo "故障转移时间:约30-45秒"
echo "假设验证:$([ $(echo "$INCIDENT_ERROR_RATE < 0.05" | bc -l) -eq 1 ] && echo "PASS" || echo "FAIL")"
echo "================================"

# 输出实验报告
cat > experiment-report-$(date +%Y%m%d-%H%M%S).md <<EOF
# 混沌实验报告:数据库故障转移

## 实验详情
- **日期**: $(date)
- **假设**: 应用程序在主数据库故障中生存,错误率<5%
- **干扰**: 杀死主PostgreSQL pod

## 结果
- **基线错误率**: ${BASELINE_ERROR_RATE}
- **故障期间峰值错误率**: ${INCIDENT_ERROR_RATE}
- **恢复时间**: 约45秒
- **数据完整性**: 已验证(无数据丢失)

## 假设验证
$([ $(echo "$INCIDENT_ERROR_RATE < 0.05" | bc -l) -eq 1 ] && echo "✅ PASS - 错误率保持在5%以下" || echo "❌ FAIL - 错误率超过5%")

## 行动项
1. 将故障转移时间从45秒减少到<30秒(调整健康检查间隔)
2. 添加连接池重试逻辑(减少客户端错误)
3. 改进数据库故障转移事件的监控警报
EOF

echo "实验报告生成。"

预期结果:

  • 故障转移时间:30-45秒
  • 峰值错误率:3-4%(低于5%阈值)
  • 数据完整性:100%保留
  • SLO影响:45秒@4%错误率=1.8秒错误预算消耗


❌ 反模式2:没有事故指挥结构

看起来像什么:

[在Slack上的P0事故中]
工程师A:"数据库宕机了!"
工程师B:"我正在重启它"
工程师C:"等等,我也在尝试重启它"
工程师A:"我们应该回滚部署吗?"
工程师B:"我不知道,也许?"
工程师C:"谁在和客户沟通?"
[15分钟的混乱,无协调行动]

为什么失败:

  • 没有单一决策者
  • 重复/冲突行动
  • 没有利益相关者沟通
  • 时间线未记录
  • 学习机会丢失

正确方法(事故指挥系统):

事故角色:
1. 事故指挥官(IC)- 做决策,协调
2. 技术领导- 调查根本原因,实施修复
3. 通信领导- 更新利益相关者
4. 记录员- 记录时间线

[事故开始]
IC:"@team P0事故声明。我是IC。@alice技术领导,@bob通信,@charlie记录员"
IC:"@alice当前状态是什么?"
Alice:"数据库主宕机,副本健康。正在调查原因。"
IC:"决定:现在提升副本为主。@alice继续。"
Bob:"发布状态页面更新:正在调查数据库问题。"
Charlie:[记录时间线:T+0: 警报触发,T+2: DB主宕机,T+5: 故障转移启动]

IC:"缓解完成。@alice确认服务健康。"
Alice:"错误率回到0.1%,延迟正常。"
IC:"事故解决。@bob最终状态更新。@charlie为事后分析编制时间线。"


质量检查表

SLO实施

  • [ ] SLIs明确定义且可测量
  • [ ] 错误预算计算并跟踪
  • [ ] Prometheus/监控查询验证
  • [ ] 设置警报阈值(避免警报疲劳)
  • [ ] 错误预算政策文档化

事故响应

  • [ ] 所有关键服务都有运行手册
  • [ ] 事故指挥角色定义
  • [ ] 通信模板准备
  • [ ] 值班轮换可持续(<5页/周)
  • [ ] 事后分析流程建立(无责任)

高可用性

  • [ ] 多AZ部署验证
  • [ ] 自动故障转移测试
  • [ ] RTO/RPO文档并验证
  • [ ] 灾难恢复每季度测试
  • [ ] 混沌实验每月运行

这个SRE技能提供了生产就绪的可靠性工程实践,强调SLOs、事故管理和持续改进。