3. 性能监控与数据采集:关键性能指标(KPI)、监控工具(Prometheus/Grafana)、日志采集与分析

性能调优这件事,说白了就是一场「数据驱动的战争」。没有数据,你连问题在哪都不知道,更别提怎么优化了。我见过太多团队,上来就拍脑袋改配置,结果越改越糟。

所以这一章,咱们聊聊怎么把监控和数据采集这件事做扎实。我会从三个层面展开:关键性能指标(KPI)、监控工具链(Prometheus + Grafana)、日志采集与分析。这三者缺一不可,构成了性能调优的「眼睛」和「耳朵」。

3.1 关键性能指标(KPI)—— 你得知道看什么

监控的第一步,不是装工具,而是定义指标。你想想看,如果连什么是「正常」都不知道,那告警还有什么意义?

我个人习惯把 KPI 分成四大类:

分类 典型指标 说明
吞吐量 QPS、TPS、RPS 单位时间内能处理多少请求
延迟 P50、P90、P99、P999 请求处理耗时分布,P99 是关键
错误率 HTTP 5xx、业务异常率 错误请求占总请求的比例
饱和度 CPU、内存、磁盘 IO、网络带宽 资源使用率,接近极限时性能会急剧下降

核心原则:不要只看平均值。平均值会掩盖真相。P99 延迟才是用户真实感受到的「卡顿」。我在项目中遇到过,平均延迟只有 50ms,但 P99 高达 2s —— 这意味着 1% 的用户体验极差。

另外,我建议你关注一个容易被忽略的指标:GC 暂停时间。对于 Java 应用,GC 暂停是延迟抖动的主要来源。我曾经在一个金融项目中,就是因为 Full GC 导致 P99 从 10ms 飙升到 500ms,排查了整整两天才定位到问题。

3.2 监控工具链:Prometheus + Grafana

工具选型上,我强烈推荐 Prometheus + Grafana 这套组合。为什么?因为它是云原生时代的标配,生态成熟,社区活跃。

3.2.1 Prometheus:时序数据库 + 采集器

Prometheus 的核心是拉模型(Pull Model)。它会定期从你的服务端点拉取指标数据。这种设计的好处是:

  • 服务无需主动上报,只需要暴露一个 /metrics 端点
  • 采集频率可控,你可以根据业务重要性调整 scrape_interval
  • 故障隔离,采集器挂了不影响业务服务

一个典型的 Prometheus 配置长这样:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'strategy-engine'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/actuator/prometheus'
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):.*'
        replacement: '${1}'
        target_label: instance

小技巧:scrape_interval 不要设得太短。15s 对于大多数场景已经足够。设成 1s 反而会给业务服务带来不必要的压力。我见过有人设成 5s,结果 Prometheus 本身成了性能瓶颈。

3.2.2 Grafana:可视化面板

Prometheus 负责存数据,Grafana 负责把数据变成看得懂的图表。我个人习惯把仪表盘分成三层:

  1. 全局概览层:QPS、错误率、P99 延迟,一眼看出系统健康状态
  2. 资源层:CPU、内存、GC、线程数,定位资源瓶颈
  3. 业务层:特定业务指标,比如策略命中率、规则执行耗时

这里有个坑,我踩过不止一次:Grafana 的查询不要写得太复杂。尤其是用 PromQL 做多表 join 或者子查询,性能会非常差。我曾经写了一个查询,每次加载面板要跑 30 秒,后来拆成两个简单查询,瞬间降到 2 秒。

3.3 日志采集与分析

指标是「是什么」,日志是「为什么」。当指标告警时,你第一件事就是去看日志。

3.3.1 日志采集架构

我推荐使用 Filebeat + Logstash + Elasticsearch 这套经典组合。Filebeat 负责采集,Logstash 负责解析和过滤,ES 负责存储和检索。

下面这张图展示了完整的日志采集链路:

日志采集与分析链路 应用服务 Filebeat Logstash Elasticsearch 说明: Filebeat 轻量采集,不丢日志;Logstash 做解析和过滤;ES 提供全文检索。 建议日志格式统一为 JSON,方便 Logstash 自动解析。

3.3.2 日志格式规范

日志格式这件事,看似简单,但做不好会让人抓狂。我建议统一使用 JSON 格式,包含以下字段:

{
  "timestamp": "2025-03-15T10:30:00.123Z",
  "level": "ERROR",
  "logger": "com.example.StrategyEngine",
  "thread": "http-nio-8080-exec-3",
  "message": "策略执行超时",
  "context": {
    "strategyId": "S12345",
    "elapsedMs": 5000,
    "userId": "U67890"
  },
  "exception": "java.util.concurrent.TimeoutException"
}

注意:千万不要在日志里打印敏感信息,比如密码、身份证号、银行卡号。我曾经在一个项目中,因为日志里打印了用户手机号,被安全团队通报批评。建议在 Logstash 层面做脱敏处理。

3.3.3 日志分析实战

日志采集上来之后,怎么分析?我常用的方法有:

  • 错误聚合:按 exception 类型分组,统计出现次数,快速定位高频错误
  • 耗时分析:按请求 ID 串联日志,计算每个环节的耗时,找到瓶颈
  • 异常检测:设置基线,当错误率突然飙升时自动告警

举个例子,有一次线上 P99 延迟突然从 50ms 涨到 200ms。我通过日志分析发现,某个策略的数据库查询耗时从 10ms 变成了 150ms。进一步排查发现,是因为数据库索引失效了。如果没有日志,这种问题根本无从下手。

3.4 小结

监控和数据采集,是性能调优的基石。记住三个要点:

  • 指标要精准:关注 P99 延迟和错误率,别被平均值骗了
  • 工具要趁手:Prometheus + Grafana 是标配,用好 PromQL 和仪表盘分层
  • 日志要规范:JSON 格式、统一字段、脱敏处理,日志是最后的救命稻草