强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

微服务拆分精讲 / 第 11 章:可观测性

第 11 章:可观测性

看不见就管不了。微服务的可观测性不是锦上添花,而是生死攸关的基础设施。


11.1 可观测性三大支柱

11.1.1 概念

┌──────────────────────────────────────────────────────────────┐
│               可观测性 (Observability) 三大支柱               │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│          ┌─────────────────────────────────────┐            │
│          │         可观测性 (Observability)      │            │
│          └────────────────┬────────────────────┘            │
│              ┌────────────┼────────────┐                    │
│              ▼            ▼            ▼                    │
│        ┌──────────┐ ┌──────────┐ ┌──────────┐              │
│        │  指标     │ │  日志     │ │  链路追踪  │              │
│        │ Metrics  │ │  Logs    │ │ Traces   │              │
│        ├──────────┤ ├──────────┤ ├──────────┤              │
│        │ "系统    │ │ "发生了  │ │ "请求经过 │              │
│        │  健康吗?"│ │  什么?" │ │  了哪里?"│              │
│        ├──────────┤ ├──────────┤ ├──────────┤              │
│        │ 时序数据  │ │ 文本记录  │ │ 请求链路  │              │
│        │ 聚合统计  │ │ 结构化   │ │ 耗时分析  │              │
│        ├──────────┤ ├──────────┤ ├──────────┤              │
│        │Prometheus│ │  ELK/Loki│ │ Jaeger/  │              │
│        │ Grafana  │ │          │ │ Zipkin   │              │
│        └──────────┘ └──────────┘ └──────────┘              │
│                                                              │
│  三者关系:                                                  │
│  Metrics 告诉你 "有问题" → Logs 告诉你 "什么问题"            │
│  → Traces 告诉你 "在哪里出了问题"                            │
└──────────────────────────────────────────────────────────────┘

11.1.2 对比

维度指标 (Metrics)日志 (Logs)链路追踪 (Traces)
数据类型数值型文本型结构化
存储时序数据库文档数据库追踪存储
查询聚合查询全文搜索链路查询
典型工具PrometheusELK/LokiJaeger/Zipkin
关注点趋势/告警详情/排错调用链/瓶颈

11.2 指标监控(Metrics)

11.2.1 指标类型

类型说明示例
Counter只增不减的计数器HTTP 请求总数、错误总数
Gauge可增可减的瞬时值内存使用量、CPU 使用率、队列长度
Histogram数据分布(分桶统计)请求延迟分布
Summary分位数统计P50/P95/P99 延迟
  指标类型可视化:

  Counter (累计)             Gauge (瞬时值)
  ─────────────             ─────────────
  ▲  requests                ▲  memory
  │      /                  │  /\/\/\
  │     /                   │ /      \
  │    /                    │/        \
  │   /                     │
  └──────────▶ t            └──────────▶ t
  (只增不减)                 (上下波动)

  Histogram (分布)           Summary (分位数)
  ─────────────             ─────────────
  ▲  latency                 ▲  P99=500ms
  │  ██                     │  ────────
  │  ████                   │  P95=200ms
  │  ██████                 │  ────────
  │  ████████               │  P50=50ms
  └──────────▶ ms            └──────────
  (分桶统计)                 (百分位)

11.2.2 Prometheus 架构

┌──────────────────────────────────────────────────────────────┐
│                   Prometheus 架构                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │ 服务 A   │  │ 服务 B   │  │ 服务 C   │  暴露 /metrics   │
│  │ /metrics │  │ /metrics │  │ /metrics │                  │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘                  │
│       │              │              │                        │
│       └──────────────┼──────────────┘                        │
│                      ▼                                      │
│            ┌──────────────────┐                              │
│            │   Prometheus     │                              │
│            │   Server         │                              │
│            │                  │                              │
│            │  ┌────────────┐ │                              │
│            │  │  TSDB      │ │  时序数据库                   │
│            │  │ (本地存储)  │ │                              │
│            │  └────────────┘ │                              │
│            │                  │                              │
│            │  ┌────────────┐ │                              │
│            │  │  PromQL    │ │  查询语言                     │
│            │  └────────────┘ │                              │
│            │                  │                              │
│            │  ┌────────────┐ │     ┌──────────────────┐    │
│            │  │ Alertmanager│──────▶│  告警通知         │    │
│            │  └────────────┘ │     │  (邮件/钉钉/Slack)│    │
│            └────────┬─────────┘     └──────────────────┘    │
│                     │                                        │
│                     ▼                                        │
│            ┌──────────────────┐                              │
│            │    Grafana       │  可视化仪表盘                 │
│            └──────────────────┘                              │
└──────────────────────────────────────────────────────────────┘

11.2.3 Prometheus 配置

# prometheus.yml
global:
  scrape_interval: 15s        # 采集间隔
  evaluation_interval: 15s    # 规则评估间隔

scrape_configs:
  - job_name: 'user-service'
    metrics_path: '/actuator/prometheus'  # Spring Boot Actuator
    static_configs:
      - targets: ['user-service:8080']
        labels:
          service: user-service
          env: production

  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

rule_files:
  - "alert_rules.yml"

11.2.4 PromQL 常用查询

# HTTP 请求速率 (QPS)
rate(http_requests_total[5m])

# 错误率
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100

# P99 延迟
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

# 内存使用率
process_resident_memory_bytes / 1024 / 1024

# 每个服务的请求速率
sum by (service) (rate(http_requests_total[5m]))

11.2.5 告警规则

# alert_rules.yml
groups:
  - name: microservice_alerts
    rules:
      # 错误率超过 5%
      - alert: HighErrorRate
        expr: |
          rate(http_requests_total{status=~"5.."}[5m])
          / rate(http_requests_total[5m]) > 0.05
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "服务 {{ $labels.service }} 错误率过高"
          description: "错误率: {{ $value | humanizePercentage }}"

      # P99 延迟超过 500ms
      - alert: HighLatency
        expr: |
          histogram_quantile(0.99,
            rate(http_request_duration_seconds_bucket[5m])) > 0.5
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "服务 {{ $labels.service }} P99 延迟过高"
          description: "P99 延迟: {{ $value | humanizeDuration }}"

      # 服务实例数为 0
      - alert: ServiceDown
        expr: up{job=~".*-service"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "服务 {{ $labels.job }} 不可用"

11.3 日志聚合(Logging)

11.3.1 结构化日志

  ❌ 非结构化日志(难以搜索和分析)
  2026-05-10 10:30:00 INFO OrderService - 用户张三创建了订单,金额299元

  ✅ 结构化日志(JSON 格式,便于搜索和聚合)
  {
    "timestamp": "2026-05-10T10:30:00+08:00",
    "level": "INFO",
    "service": "order-service",
    "traceId": "abc-123-def",
    "spanId": "span-001",
    "userId": "user-001",
    "orderId": "ORD-20260510-001",
    "amount": 299.00,
    "message": "Order created successfully"
  }

11.3.2 ELK Stack 架构

┌──────────────────────────────────────────────────────────────┐
│                    ELK Stack 架构                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │ 服务 A   │  │ 服务 B   │  │ 服务 C   │  输出日志         │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘                  │
│       │              │              │                        │
│       └──────────────┼──────────────┘                        │
│                      ▼                                      │
│            ┌──────────────────┐                              │
│            │   Filebeat       │  日志采集器                   │
│            └────────┬─────────┘                              │
│                     ▼                                        │
│            ┌──────────────────┐                              │
│            │   Logstash       │  日志处理/转换                │
│            │   (或直接到 ES)  │                              │
│            └────────┬─────────┘                              │
│                     ▼                                        │
│            ┌──────────────────┐                              │
│            │ Elasticsearch    │  存储和搜索                   │
│            └────────┬─────────┘                              │
│                     ▼                                        │
│            ┌──────────────────┐                              │
│            │    Kibana        │  可视化/查询                  │
│            └──────────────────┘                              │
└──────────────────────────────────────────────────────────────┘

11.3.3 Loki:轻量级日志方案

  Loki (Grafana Labs) 架构:

  ┌──────────┐         ┌──────────┐         ┌──────────┐
  │ Promtail │────────▶│  Loki    │────────▶│ Grafana  │
  │ (采集)   │         │ (存储)   │         │ (查询)   │
  └──────────┘         └──────────┘         └──────────┘

  特点:
  • 只索引标签 (label),不索引日志内容 → 存储成本低
  • 与 Prometheus 标签体系一致
  • 使用 LogQL 查询语言
  • 轻量级,资源占用少

11.3.4 日志查询示例

  Kibana (KQL) 查询示例:

  # 查询 order-service 的错误日志
  service: "order-service" AND level: "ERROR"

  # 查询特定订单的日志
  orderId: "ORD-20260510-001"

  # 查询最近 1 小时的超时错误
  service: "payment-service" AND message: "timeout"
  AND @timestamp >= "now-1h"

  Grafana Loki (LogQL) 查询示例:

  {service="order-service"} |= "error" | logfmt | duration > 1s
  {service="order-service", level="ERROR"} | json | userId="user-001"

11.4 链路追踪(Distributed Tracing)

11.4.1 核心概念

概念说明
Trace一个完整请求的端到端调用链
SpanTrace 中的一个操作单元(如一次 RPC 调用)
TraceID全局唯一标识,贯穿整个请求链
SpanID单个 Span 的唯一标识
ParentSpanID父 Span 的 ID,构成调用树
  Trace 示例:用户下单

  TraceID: abc-123-def
  │
  ├── Span 1: API Gateway (10ms)
  │   └── Span 2: Order Service - createOrder (150ms)
  │       ├── Span 3: User Service - getUser (20ms)
  │       ├── Span 4: Product Service - getProduct (30ms)
  │       ├── Span 5: Inventory Service - deductStock (50ms)
  │       └── Span 6: Payment Service - pay (80ms)
  │           └── Span 7: Bank API - transfer (60ms)
  │
  时间轴:
  |---Gateway---|
       |---Order Service (150ms)---|
            |User| |Product| |---Inventory---| |---Payment---|
                                            |---Bank API---|
  0ms       10ms  30ms  60ms         110ms           150ms

11.4.2 OpenTelemetry

OpenTelemetry(OTel)是 CNCF 的可观测性标准,统一了 Metrics、Logs、Traces 的采集。

  OpenTelemetry 架构:

  ┌──────────────────────────────────────────────────────────┐
  │                 OpenTelemetry                             │
  │                                                          │
  │  应用层 (SDK)                                            │
  │  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
  │  │ Traces   │  │ Metrics  │  │ Logs     │              │
  │  │ API/SDK  │  │ API/SDK  │  │ API/SDK  │              │
  │  └────┬─────┘  └────┬─────┘  └────┬─────┘              │
  │       └──────────────┼──────────────┘                    │
  │                      ▼                                    │
  │  ┌────────────────────────────────────────────────────┐  │
  │  │          OpenTelemetry Collector                   │  │
  │  │                                                    │  │
  │  │  Receivers ──▶ Processors ──▶ Exporters           │  │
  │  │  (OTLP/Jaeger)  (过滤/批处理)  (Prometheus/Jaeger) │  │
  │  └────────────────────────────────────────────────────┘  │
  │                      │                                    │
  │       ┌──────────────┼──────────────┐                    │
  │       ▼              ▼              ▼                    │
  │  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
  │  │ Jaeger   │  │Prometheus│  │  Loki    │              │
  │  │ (Traces) │  │(Metrics) │  │ (Logs)   │              │
  │  └──────────┘  └──────────┘  └──────────┘              │
  │                      │                                    │
  │                      ▼                                    │
  │               ┌──────────┐                               │
  │               │ Grafana  │  统一可视化                    │
  │               └──────────┘                               │
  └──────────────────────────────────────────────────────────┘

11.4.3 Spring Boot 集成 OpenTelemetry

<!-- pom.xml -->
<dependency>
    <groupId>io.opentelemetry.instrumentation</groupId>
    <artifactId>opentelemetry-spring-boot-starter</artifactId>
</dependency>
# application.yml
otel:
  service:
    name: order-service
  exporter:
    otlp:
      endpoint: http://otel-collector:4317
  traces:
    sampler:
      probability: 0.1  # 采样率 10%

11.4.4 链路追踪工具对比

维度JaegerZipkinSkyWalkingTempo
开发者UberTwitterApacheGrafana Labs
存储ES/Cassandra/KafkaES/Cassandra/MySQLES/H2/MySQL对象存储
语言支持多语言多语言Java 为主(+Agent)多语言
服务拓扑
采样策略多种多种多种多种
与 Grafana 集成⚠️✅ 原生

11.5 Grafana 统一仪表盘

  Grafana 仪表盘示例:

  ┌──────────────────────────────────────────────────────────────┐
  │  微服务监控仪表盘 - 生产环境                                   │
  ├──────────────────────────────────────────────────────────────┤
  │                                                              │
  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
  │  │ 总 QPS       │  │ 总错误率      │  │ 总 P99 延迟   │      │
  │  │  12,543      │  │  0.12%       │  │  89ms        │      │
  │  │  ▲ +5%       │  │  ▼ -0.02%   │  │  ▼ -10ms     │      │
  │  └──────────────┘  └──────────────┘  └──────────────┘      │
  │                                                              │
  │  ┌─────────────────────────────────────────────────────┐   │
  │  │ 每个服务的 QPS 趋势 (折线图)                          │   │
  │  │  ▲                                                   │   │
  │  │  │    ╱╲   ╱╲                                       │   │
  │  │  │   ╱  ╲ ╱  ╲                                      │   │
  │  │  │  ╱    ╳    ╲                                     │   │
  │  │  │ ╱   ╱ ╲     ╲                                    │   │
  │  │  └──────────────────▶                               │   │
  │  └─────────────────────────────────────────────────────┘   │
  │                                                              │
  │  ┌─────────────────────┐  ┌─────────────────────┐         │
  │  │ 服务调用拓扑图       │  │ 最近错误日志          │         │
  │  │  (Loki + Tempo)     │  │  (Loki)             │         │
  │  │  GW→OS→PS→IS→PS    │  │  ERROR timeout...   │         │
  │  └─────────────────────┘  └─────────────────────┘         │
  └──────────────────────────────────────────────────────────────┘

11.6 告警体系

11.6.1 告警级别

级别触发条件通知方式响应时间
P0 (致命)服务不可用、数据丢失电话 + 短信 + 钉钉5 分钟
P1 (严重)错误率 > 5%、延迟 > 1s短信 + 钉钉15 分钟
P2 (警告)错误率 > 1%、资源 > 80%钉钉/Slack1 小时
P3 (通知)非紧急变更邮件下个工作日

11.6.2 Golden Signals(Google SRE)

信号说明PromQL
Latency请求延迟histogram_quantile(0.99, ...)
Traffic请求速率rate(http_requests_total[5m])
Errors错误率rate(http_requests_total{status=~"5.."}[5m])
Saturation资源饱和度CPU/Memory/Disk usage

11.7 业务场景:电商系统可观测性方案

  ┌──────────────────────────────────────────────────────────────┐
  │              电商系统可观测性架构                              │
  ├──────────────────────────────────────────────────────────────┤
  │                                                              │
  │  数据采集层                                                   │
  │  ┌──────────┐ ┌──────────┐ ┌──────────┐                    │
  │  │ OpenTelemetry│Promtail│ │Prometheus│                    │
  │  │ (Traces) │  │ (Logs)  │ │(Metrics) │                    │
  │  └────┬─────┘  └────┬────┘  └────┬────┘                    │
  │       └──────────────┼──────────────┘                       │
  │                      ▼                                      │
  │  数据存储层                                                   │
  │  ┌──────────┐ ┌──────────┐ ┌──────────┐                    │
  │  │  Tempo   │ │  Loki    │ │Prometheus│                    │
  │  │ (Traces) │ │ (Logs)   │ │(Metrics) │                    │
  │  └────┬─────┘  └────┬────┘  └────┬────┘                    │
  │       └──────────────┼──────────────┘                       │
  │                      ▼                                      │
  │  可视化层                                                    │
  │  ┌──────────────────────────────────────────────────────┐  │
  │  │                   Grafana                             │  │
  │  │  ┌─────────┐  ┌─────────┐  ┌─────────┐              │  │
  │  │  │ 业务大盘 │  │ 技术大盘 │  │ 告警面板 │              │  │
  │  │  │ 订单量   │  │ QPS/延迟│  │ 异常通知 │              │  │
  │  │  │ 收入     │  │ 错误率  │  │ 告警历史 │              │  │
  │  │  └─────────┘  └─────────┘  └─────────┘              │  │
  │  └──────────────────────────────────────────────────────┘  │
  │                      │                                      │
  │                      ▼                                      │
  │  告警通知层                                                   │
  │  ┌──────────┐ ┌──────────┐ ┌──────────┐                    │
  │  │ 电话告警  │ │ 钉钉/Slack│ │ 邮件告警  │                    │
  │  └──────────┘ └──────────┘ └──────────┘                    │
  └──────────────────────────────────────────────────────────────┘

⚠️ 注意事项

  1. 日志采样率——生产环境不要 100% 采集 Trace,10-20% 通常足够
  2. 日志量控制——DEBUG 级别日志不要输出到生产环境
  3. 敏感信息脱敏——日志中不要包含密码、Token、身份证号等
  4. 告警不要太多——告警疲劳比没有告警更危险
  5. 关联 TraceID——日志中必须包含 TraceID,方便关联查询

📖 扩展阅读

  1. OpenTelemetry Documentation (opentelemetry.io) — 可观测性标准
  2. Prometheus Documentation (prometheus.io) — 指标监控标准
  3. Grafana Documentation (grafana.com) — 可视化最佳实践
  4. Google SRE Book — Golden Signals 定义
  5. Observability Engineering — Charity Majors — O’Reilly 可观测性工程

本章小结

支柱工具核心作用
指标 (Metrics)Prometheus + Grafana趋势监控、告警
日志 (Logs)ELK / Loki排错、审计
链路追踪 (Traces)Jaeger / Tempo调用链分析、瓶颈定位
统一标准OpenTelemetry统一采集三大信号

📌 下一章第 12 章:测试策略 — 契约测试、集成测试、混沌工程。