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 负责把数据变成看得懂的图表。我个人习惯把仪表盘分成三层:
- 全局概览层:QPS、错误率、P99 延迟,一眼看出系统健康状态
- 资源层:CPU、内存、GC、线程数,定位资源瓶颈
- 业务层:特定业务指标,比如策略命中率、规则执行耗时
这里有个坑,我踩过不止一次:Grafana 的查询不要写得太复杂。尤其是用 PromQL 做多表 join 或者子查询,性能会非常差。我曾经写了一个查询,每次加载面板要跑 30 秒,后来拆成两个简单查询,瞬间降到 2 秒。
3.3 日志采集与分析
指标是「是什么」,日志是「为什么」。当指标告警时,你第一件事就是去看日志。
3.3.1 日志采集架构
我推荐使用 Filebeat + Logstash + Elasticsearch 这套经典组合。Filebeat 负责采集,Logstash 负责解析和过滤,ES 负责存储和检索。
下面这张图展示了完整的日志采集链路:
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 格式、统一字段、脱敏处理,日志是最后的救命稻草