第三章:性能监控体系
性能监控这事儿,我做了十几年,踩过的坑比走过的路还多。很多人一上来就堆工具,Prometheus 装了,Grafana 配了,SkyWalking 也上了,结果线上出了故障还是两眼一抹黑。为什么?因为没搞懂监控的本质。
监控说白了就三件事:指标、日志、链路。这三样东西,缺一个你都没法真正看清系统的全貌。我习惯把它们叫做「监控三要素」,今天咱们就一个一个拆开来讲。
3.1 监控三要素:指标、日志、链路
先说说这三者各自管什么。
- 指标(Metrics):告诉你系统「现在怎么样」。比如 CPU 用了多少、QPS 多少、错误率多少。它是数字化的,适合做告警和趋势分析。
- 日志(Logs):告诉你系统「发生了什么」。比如某次请求报了什么错、参数是什么。它是文本化的,适合做问题定位。
- 链路(Traces):告诉你系统「为什么慢」。比如一个请求经过了哪些服务、每个服务花了多少时间。它是结构化的,适合做性能瓶颈分析。
你想想看,如果只有指标,你只知道 CPU 飙高了,但不知道是哪个接口导致的。如果只有日志,你只能一条一条翻,效率极低。如果只有链路,你只能看到调用关系,但看不到资源消耗。所以,三者必须配合使用。
核心观点:指标用于告警,日志用于定位,链路用于分析。三者缺一不可。
我在项目中遇到过一种情况:某次线上故障,指标显示接口响应时间从 50ms 飙到了 5s,但日志里没有任何错误。后来查链路才发现,是下游的一个 Redis 集群超时了。你看,没有链路数据,你根本不知道问题出在哪一环。
3.2 Prometheus + Grafana 搭建
说到指标监控,Prometheus 和 Grafana 基本是标配了。Prometheus 负责采集和存储,Grafana 负责展示和告警。这套组合我用了很多年,稳定、灵活、社区活跃。
3.2.1 Prometheus 核心概念
Prometheus 的数据模型其实很简单:时间序列。每个时间序列由 metric 名称和一组 key-value 标签唯一标识。比如:
http_requests_total{method="GET", endpoint="/api/user", status="200"} 1024
这个数据表示:GET 请求 /api/user 接口,返回 200 的次数是 1024。Prometheus 会定期拉取这个数据,存储到本地。
它的架构也很清晰:
- Prometheus Server:核心组件,负责拉取数据、存储、查询。
- Exporters:数据采集器,比如 node_exporter 采集机器指标,mysqld_exporter 采集数据库指标。
- Pushgateway:用于短期任务的指标推送。
- Alertmanager:负责告警管理。
小技巧:我个人习惯把 Prometheus 的存储保留期设为 15 天。太短了查不到历史数据,太长了磁盘扛不住。如果你需要长期存储,可以搭配 Thanos 或 VictoriaMetrics。
3.2.2 搭建步骤
搭建其实不复杂,我直接给一个最简的 docker-compose 配置:
version: '3'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
对应的 prometheus.yml 配置:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
启动之后,访问 localhost:9090 就能看到 Prometheus 的 UI,访问 localhost:3000 就是 Grafana。在 Grafana 里添加 Prometheus 数据源,然后导入一个现成的 Dashboard(比如 Node Exporter Full),你就能看到机器的各项指标了。
注意:我曾经因为 scrape_interval 设置得太短(5s),导致 Prometheus 把生产环境的机器 CPU 打满了。建议生产环境至少设到 15s,甚至 30s。监控本身不能成为性能瓶颈。
3.2.3 告警配置
光有图表不够,还得有告警。Prometheus 的告警规则写在 rules 文件里:
groups:
- name: node_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Instance {{ $labels.instance }} CPU usage > 80%"
这个规则的意思是:如果某个机器的 CPU 使用率超过 80%,持续 5 分钟,就触发告警。Alertmanager 收到告警后,可以发邮件、钉钉、Slack 等等。
3.3 APM 工具:SkyWalking 与 Pinpoint
指标和日志都有了,但你还缺一样——链路追踪。这就是 APM(Application Performance Management)工具干的事。市面上主流的 APM 工具有 SkyWalking、Pinpoint、Jaeger、Zipkin 等。我个人用得最多的是 SkyWalking 和 Pinpoint。
3.3.1 SkyWalking
SkyWalking 是国产开源项目,对 Java 生态支持非常好。它的核心优势是:无侵入。你只需要在启动参数里加一个 javaagent,就能自动采集链路数据。
java -javaagent:/path/to/skywalking-agent.jar \
-Dskywalking.agent.service_name=my-service \
-Dskywalking.collector.backend_service=127.0.0.1:11800 \
-jar my-app.jar
启动之后,SkyWalking 会自动拦截 HTTP、RPC、数据库等调用,生成链路数据。你可以在它的 UI 上看到:
- 每个请求的完整调用链
- 每个节点的耗时
- 错误信息
- 服务拓扑图
我记得有一次,一个接口特别慢,从日志看 SQL 执行时间正常,但接口就是慢。后来用 SkyWalking 一看,发现是 HTTP 调用下游服务时,连接池满了,请求在排队。这种问题,没有链路追踪根本查不出来。
3.3.2 Pinpoint
Pinpoint 是韩国团队开发的,跟 SkyWalking 类似,也是基于字节码增强的 APM 工具。它的特点是:数据粒度更细。Pinpoint 能展示每个方法的调用次数、响应时间、甚至每个参数的采样值。
但 Pinpoint 也有缺点:资源消耗大。我曾在生产环境试过 Pinpoint,发现它会把 JVM 的 GC 时间拉高不少。如果你的机器资源比较紧张,建议优先考虑 SkyWalking。
| 特性 | SkyWalking | Pinpoint |
|---|---|---|
| 部署复杂度 | 低(支持单节点) | 中(依赖 HBase) |
| 资源消耗 | 低 | 高 |
| 数据粒度 | 中 | 细 |
| 社区活跃度 | 高(中文社区) | 中 |
| 适用场景 | 生产环境首选 | 测试环境/问题排查 |
我的建议:生产环境用 SkyWalking,稳定、轻量、够用。如果你需要做深度的代码级性能分析,可以临时部署 Pinpoint,用完就关掉。
3.4 知识体系总览
下面这张图是我自己整理的监控体系结构,你可以对照着理解:
从这张图你可以看到,监控体系分三层:要素层定义你要监控什么,工具层解决怎么采集和展示,数据层解决怎么存储和查询。每一层都有对应的技术选型。
嗯,到这里,监控体系的核心内容就讲完了。记住一句话:没有监控的系统,就像闭着眼睛开车。你永远不知道下一秒会撞上什么。
避坑指南:我曾经在一个项目里,把所有监控指标都堆到同一个 Grafana Dashboard 上,结果图表太多,根本看不清楚。后来我学乖了,按服务拆分 Dashboard,每个服务一个,只展示关键指标。简洁,才能高效。
想要更多资料,联系可可