1、上线不是终点,是起点

很多人以为"代码上线"就完事了。可系统的真正考验在上线之后:它要一天 24 小时运行、要面对真实流量、会悄悄退化、会半夜出故障。

运维不是"给服务器续命",而是"让系统持续健康地服务用户"。 本课讲运维的核心:可观测性(日志/指标/链路)、告警设计、以及SLO 与错误预算。

2、可观测性三大支柱

系统出问题时,你需要"看见内部发生了什么"。靠三样东西:

支柱回答什么例子
日志(Logs)发生了什么具体事件?"用户 123 登录失败:密码错误"
指标(Metrics)系统整体状态如何?QPS、P95 延迟、错误率、CPU
链路追踪(Traces)一个请求经过了哪些环节?请求 → 网关 → 订单服务 → 库存服务(各耗时)
一次用户请求的"可观测"过程:

日志:   [10:00:01] order=#88 created by user=123
指标:   http_requests_total=1024, p95_latency=210ms, error_rate=0.3%
链路:   gateway(5ms) → order-svc(180ms) → db(120ms) ← DB 是瓶颈!

日志:结构化(JSON)比纯文本好检索;分级(DEBUG/INFO/WARN/ERROR);关键:别记敏感信息(密码、token、身份证)。

{"time":"2026-01-01T10:00:01Z","level":"ERROR","service":"order","user":123,"msg":"payment failed","code":"CARD_DECLINED","trace_id":"abc123"}

指标:常见四类(USE 法 / RED 法):

RED(服务视角):  Rate 请求率 / Errors 错误 / Duration 耗时
USE(资源视角):  Utilization 利用率 / Saturation 饱和 / Errors 错误

链路追踪:给每个请求一个 trace_id,串起跨服务调用,定位"到底哪一段慢"。

工具:Prometheus + Grafana(指标)、ELK/Loki(日志)、Jaeger/Tempo(追踪)。

3、告警:宁可少响,不可误响

告警疲劳(Alert Fatigue) 是运维的头号杀手:如果告警天天响、大多是误报,团队就会无视它,真出事时也麻木了。

好告警的原则:

原则说明
可行动(Actionable)收到告警知道该做什么,不知道就是噪音
指向症状而非原因告警"用户请求失败率高",而非"某个磁盘满了"(后者可能是原因,留给诊断)
有阈值与持续时间"错误率 > 5% 持续 5 分钟",避免瞬时抖动误报
分级P0 打电话、P1 发消息、P2 邮件
去重与聚合一次故障别发 500 条告警
有归属每条告警知道找谁
# Prometheus 告警规则示例
groups:
  - name: api
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 5m                          # 持续 5 分钟才告警
        labels:
          severity: P1
        annotations:
          summary: "API 5xx 错误率 >5%"
          runbook: "https://wiki/runbook/high-error-rate"

"Runbook" 很重要:每个告警配有处置手册,值班的人照着做即可。

4、SLO 与错误预算:把"可靠性"量化

"要 100% 可用"是不现实的(也不可能,成本无限)。工程上的做法是把可靠性变成可管理的目标:

SLI(指标):  实际测量值,如"请求成功率 = 99.95%"
SLO(目标):  我们希望达到的水平,如"成功率 ≥ 99.9%"
SLA(协议):  对客户的承诺(往往带赔偿条款),通常比 SLO 宽松

错误预算(Error Budget)= 1 - SLO
  若 SLO=99.9%,则每月允许约 43 分钟不可用

错误预算的妙用:把"要不要发新功能"变成数据决策:

错误预算充足  → 可以大胆发版、做实验
错误预算耗尽  → 冻结发布,集中力量修稳定性

这样开发(想快)和运维(想稳)就不再是对立面——用同一个数字说话。

5、值班(On-call)与响应

系统 24×7 运行,就得有人随时能响应故障:

  • 轮值制度:轮班,避免一个人长期疲惫。
  • 清晰升级路径:第一时间找不到人 → 多久升级给谁。
  • 预案(Runbook):常见故障怎么处置、怎么回滚。
  • 事后复盘:每次故障都复盘(第 28 课)。
  • 健康文化:值班的人不是"背锅侠",是"守夜人"。
痛苦指标:如果一个人经常半夜被叫醒,说明系统或告警需要改进——从"人肉扛"转向"系统自愈"。

6、让系统更"自愈"

成熟的运维会尽量自动化响应:

  • 自动重启:进程挂了,supervisor/systemd/k8s 自动拉起。
  • 自动扩容:流量涨,自动加实例(HPA/Auto Scaling)。
  • 自动降级:依赖挂了,返回缓存/默认值,而不是全挂。
  • 自动熔断:下游持续失败,快速失败,别拖垮自己。
  • 限流:保护自己不被流量冲垮。
# 简单降级示例:推荐服务挂了就返回热门列表
def get_recommendations(user):
    try:
        return recommend_service.query(user, timeout=0.5)
    except (Timeout, ConnectionError):
        return fallback.get_popular_items()   # 降级,别让页面白屏

7、常见误区

误区问题正解
无监控凭感觉出问题不知道日志/指标/追踪三支柱
告警太多告警疲劳、真报警被忽略可行动、分级、去重
追求 100% 可用成本无限、不可行用 SLO + 错误预算
日志带敏感信息泄露隐私/合规风险脱敏、禁记密码 token
只监控机器不监控业务机器正常但业务挂了业务指标(下单成功率)也要监控
值班靠一个人硬扛疲惫、易出错轮值 + 自动化

8、动手实验 🎯

任务:给贯穿项目「团队任务清单」搭建可观测性。

  1. 结构化日志:把应用日志改成 JSON,包含 trace_id、level、关键字段,且不含敏感信息。
  2. 暴露指标:用 Prometheus 客户端暴露 /metrics,包含请求数、错误数、耗时直方图。
  3. 建看板:用 Grafana(或本地替代)画出 QPS、P95 延迟、错误率四张图。
  4. 配 3 条告警:错误率、延迟、实例宕机各一条,带 for 持续时间与 runbook 链接。
  5. 定义 SLO:为"任务列表接口"写一个 SLO(如 P95 < 500ms、成功率 ≥ 99.9%),算出月度错误预算。
  6. 实现降级:给某个外部依赖调用加超时 + 降级逻辑,模拟依赖挂掉时服务仍可用。
  7. 反思:如果半夜收到告警,你希望告警里包含哪些信息,才能不慌?

下一课:事故响应与复盘。

9、今天你带走的三句话

  1. 可观测性三支柱:日志(发生了什么)/ 指标(整体状态)/ 链路(请求去了哪)。
  2. 告警要"可行动、指向症状、有持续时间",避免告警疲劳。
  3. 用 SLO + 错误预算把可靠性量化,让"快"和"稳"用同一把尺子。

下一课:事故响应与复盘。

标签: 软件工程, 项目管理, 开发流程

添加新评论