面向对象:后端/架构/运维/平台工程团队,希望把“出了问题才看日志”升级为“分钟级定位与可量化治理”
交付目标:一套可复制的可观测性平台(Metrics/Logs/Traces),配套埋点规范、仪表盘、告警与故障定位手册

目录

  1. 总览与交付清单
  2. 可观测性三件套与选型说明
  3. 最小可用架构与端口规划
  4. Docker Compose 一键部署(可直接跑)
  5. Spring Boot 接入(Metrics/Logs/Traces)
  6. Node.js 接入(可选)
  7. Nginx/网关:请求链路贯通(TraceID/RequestID)
  8. 仪表盘模板与关键指标
  9. 告警策略:从“报警噪音”到“可行动”
  10. 故障定位 SOP:30 分钟定位到 1 分钟
  11. 生产化要点:容量、保留、采样、安全
  12. 验收清单与交付打包
  13. FAQ

1. 总览与交付清单

你将得到什么

  • 一个能跑起来的可观测性平台(Grafana + Prometheus + Loki + Tempo + OTel Collector)
  • 一套“埋点与字段规范”(让跨服务可搜索、可串联)
  • 关键仪表盘与告警思路(延迟/错误/饱和度/容量)
  • 一份故障定位 SOP(按图索骥)

交付物(建议随文提供)

  • docker-compose.yml(平台一键启动)
  • Grafana 仪表盘 JSON(建议 2~4 个:服务总览、JVM、慢请求、依赖拓扑)
  • 告警规则示例(Prometheus rules)
  • 日志字段规范(JSON 模板)
  • 故障定位 SOP(值班可用)

2. 可观测性三件套与选型说明

2.1 Metrics(指标)

适合回答:

  • “服务慢不慢?慢在哪个分位?”
  • “错误率是否升高?哪个接口最异常?”
  • “CPU/内存/线程池/GC 是否成为瓶颈?”

2.2 Logs(日志)

适合回答:

  • “具体错误栈是什么?发生在什么参数/什么用户/什么版本?”
  • “同一次请求在多个服务里发生了什么?”

2.3 Traces(链路追踪)

适合回答:

  • “一次请求跨了哪些服务?每段耗时多少?哪里慢?”
  • “外部依赖(DB/Redis/HTTP)哪个在拖后腿?”

2.4 为什么推荐 OpenTelemetry

OpenTelemetry(OTel)解决的是“统一标准与采集协议”的问题:

  • 统一埋点/采集/导出标准,避免被单一厂商锁死
  • Collector 能在边界做数据清洗、采样、脱敏、路由

3. 最小可用架构与端口规划

推荐最小架构(本地/测试/小团队可用):

  • Grafana:可视化与告警聚合
  • Prometheus:抓取指标
  • Loki:日志存储与查询
  • Tempo:Trace 存储
  • OTel Collector:统一接入与转发

端口规划(示例)

  • 3000:Grafana
  • 9090:Prometheus
  • 3100:Loki
  • 3200:Tempo
  • 4317:OTLP gRPC(应用上报 traces/metrics/logs)
  • 4318:OTLP HTTP(可选)

4. Docker Compose 一键部署(可直接跑)

把下面保存为 docker-compose.yml,直接启动:

services:
  grafana:
    image: grafana/grafana:latest
    container_name: obs-grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - ./data/grafana:/var/lib/grafana
    depends_on:
      - prometheus
      - loki
      - tempo
    restart: unless-stopped

  prometheus:
    image: prom/prometheus:latest
    container_name: obs-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./data/prometheus:/prometheus
    restart: unless-stopped

  loki:
    image: grafana/loki:2.9.6
    container_name: obs-loki
    ports:
      - "3100:3100"
    command: -config.file=/etc/loki/local-config.yaml
    restart: unless-stopped

  tempo:
    image: grafana/tempo:latest
    container_name: obs-tempo
    ports:
      - "3200:3200"
      - "4317:4317"
    command: [ "-config.file=/etc/tempo.yaml" ]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml:ro
      - ./data/tempo:/var/tempo
    restart: unless-stopped

  otel-collector:
    image: otel/opentelemetry-collector-contrib:latest
    container_name: obs-otel-collector
    ports:
      - "4318:4318"
      - "4317:4317"
    volumes:
      - ./otel-collector.yaml:/etc/otelcol-contrib/config.yaml:ro
    restart: unless-stopped

配套配置文件(最小可用)

prometheus.yml(示例:抓取你应用的 /actuator/prometheus

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: app
    metrics_path: /actuator/prometheus
    static_configs:
      - targets: ["host.docker.internal:8080"]

tempo.yaml(示例:接收 OTLP 并本地存储)

server:
  http_listen_port: 3200

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317

storage:
  trace:
    backend: local
    local:
      path: /var/tempo/traces

otel-collector.yaml(示例:接收 OTLP,转发到 Tempo)

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:

exporters:
  otlp:
    endpoint: tempo:4317
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]

启动:

docker compose up -d

访问:

  • Grafana:http://localhost:3000(admin/admin)

5. Spring Boot 接入(Metrics/Logs/Traces)

5.1 指标:Micrometer + Prometheus

依赖(Maven 示例):

  • spring-boot-starter-actuator
  • micrometer-registry-prometheus

配置要点:

  • 打开 /actuator/prometheus
  • 采集 JVM、HTTP Server、数据库连接池等指标

最小配置示例(application.yml):

management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus
  endpoint:
    health:
      show-details: when_authorized

5.2 Trace:OTel Java Agent(最快落地)

如果你追求“最快见效”,推荐先用 Java Agent:

  • 不改业务代码
  • 先把 Trace 跑通,再逐步补自定义 span 与属性

启动参数示例(仅示例,按你的环境放到启动脚本/容器环境变量):

java \
  -javaagent:opentelemetry-javaagent.jar \
  -Dotel.service.name=demo-spring \
  -Dotel.exporter.otlp.endpoint=http://localhost:4317 \
  -Dotel.traces.exporter=otlp \
  -jar app.jar

5.3 日志:统一 JSON 字段 + TraceID 贯通

目标:用 Loki 查询时能按 trace_idserviceenvversion 快速过滤。

建议字段规范(示例):

  • timestamp
  • level
  • service
  • env
  • version
  • trace_id
  • span_id
  • request_id
  • user_id(如有,注意脱敏/权限)
  • path
  • latency_ms
  • error(布尔)

6. Node.js 接入(可选)

Node 端建议也用 OTel SDK,上报到 Collector(统一入口):

  • 统一服务名、环境、版本
  • 统一采样策略

7. Nginx/网关:请求链路贯通(TraceID/RequestID)

原则:入口层必须做到“每个请求都有一个可追踪的 ID”,并透传到后端与日志。

建议做法:

  • 若已在应用侧生成 TraceID:入口层透传即可
  • 若入口层先生成 RequestID:写入 header,并在后端日志中输出

8. 仪表盘模板与关键指标

建议你至少提供以下 4 个仪表盘(读者最有感):

  • 服务总览:QPS、P95、错误率、CPU/内存、实例数
  • JVM 运行态:堆/非堆、GC 次数与耗时、线程、类加载
  • 接口 TopN:最慢/最热/错误最多
  • 依赖总览:DB/Redis/外部 HTTP 的耗时与错误率

黄金指标(建议按服务维度固定输出):

  • 延迟(Latency):P50/P90/P95/P99
  • 流量(Traffic):QPS
  • 错误(Errors):5xx、业务错误码分布
  • 饱和度(Saturation):CPU、线程池、连接池、队列长度

9. 告警策略:从“报警噪音”到“可行动”

告警不是越多越好,而是要“可行动”。

建议分级:

  • P0:核心链路不可用(错误率暴涨、全站 5xx、关键依赖崩)
  • P1:核心链路退化(P95 明显升高、队列堆积、连接池耗尽)
  • P2:风险提示(磁盘水位、证书到期、慢查询增长)

告警必须包含:

  • 触发条件(阈值与时间窗口)
  • 影响范围(服务/接口/地域)
  • 处理建议(SOP 入口、回滚/降级开关)

10. 故障定位 SOP:30 分钟定位到 1 分钟

给你一条可复制的定位链路:

  1. 先看仪表盘:是否是全局问题还是单服务问题
  2. 看 TopN:最慢/错误最多的接口是哪几个
  3. 查 Trace:定位慢在 DB 还是外部 HTTP
  4. 查 Logs:按 trace_id 把同一次请求的日志串起来
  5. 定位后做动作:限流/降级/回滚/扩容/修复

11. 生产化要点:容量、保留、采样、安全

容量与保留

  • 日志:明确保留天数与存储成本,避免 Loki 磁盘爆
  • Trace:默认全量会很快爆炸,务必做采样与保留策略

采样建议(按环境)

  • dev:100%
  • test:20%~50%
  • prod:1%~10%(关键链路可提高)

安全建议

  • 日志脱敏(手机号、身份证、token)
  • 访问控制(Grafana 账号、只读角色、最小权限)
  • 网络隔离(仅内网访问,必要时加 VPN/堡垒机)

12. 验收清单与交付打包

验收清单

  • Grafana 能打开,数据源可用
  • Prometheus 能抓到应用指标
  • 生成 Trace 后能在 Tempo 中检索并在 Grafana 中跳转查看
  • 日志能按 service/env/trace_id 查询
  • 告警规则能触发一次演练(模拟错误率/延迟升高)

交付打包(建议)

  • /deploy:compose 与配置
  • /dashboards:Grafana JSON
  • /alerts:规则模板
  • /runbook:故障定位 SOP

13. FAQ

Q:为什么 Grafana 有数据但 Trace 看不到?
A:先检查应用是否把 OTLP 发到了 Collector/Tempo,确认 4317 端口连通,再确认 service.name 是否一致。

Q:日志怎么和 Trace 串起来?
A:关键是日志字段里要有 trace_id,并确保请求入口到下游都透传上下文。

Q:一上生产数据量就爆炸怎么办?
A:第一优先级做采样;第二做保留与降采样;第三按业务价值分层存储。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐