监控告警系统设计
问题
如何设计一套完善的监控告警系统,覆盖基础设施、应用、业务三层监控?
答案
三层监控体系
监控系统架构
Prometheus 核心概念
| 概念 | 说明 |
|---|---|
| Metric | 指标,四种类型:Counter、Gauge、Histogram、Summary |
| Label | 标签,多维数据模型 |
| Scrape | 拉取模式,Prometheus 定期拉取目标的 /metrics |
| PromQL | 查询语言,支持聚合、函数、向量运算 |
| AlertRule | 告警规则,基于 PromQL 触发 |
Spring Boot 集成 Prometheus
application.yml
management:
endpoints:
web:
exposure:
include: health,prometheus,metrics
metrics:
export:
prometheus:
enabled: true
tags:
application: order-service # 全局标签
自定义业务指标
@Component
public class OrderMetrics {
private final Counter orderCounter;
private final Timer orderTimer;
public OrderMetrics(MeterRegistry registry) {
// Counter:只增不减,适合累计值
this.orderCounter = Counter.builder("order.created.total")
.description("Total orders created")
.tag("channel", "app")
.register(registry);
// Timer:记录耗时分布
this.orderTimer = Timer.builder("order.create.duration")
.description("Order creation duration")
.publishPercentiles(0.5, 0.95, 0.99) // P50/P95/P99
.register(registry);
}
public void recordOrderCreated() {
orderCounter.increment();
}
public void recordDuration(Runnable task) {
orderTimer.record(task);
}
}
告警规则配置
prometheus-alert-rules.yml
groups:
- name: application
rules:
# 错误率超过 5% 持续 2 分钟告警
- alert: HighErrorRate
expr: |
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/ sum(rate(http_server_requests_seconds_count[5m])) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "错误率超过 5%"
# P99 延迟超过 2 秒
- alert: HighLatency
expr: |
histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri)) > 2
for: 3m
labels:
severity: warning
annotations:
summary: "P99 延迟超过 2s"
# JVM 堆内存使用超过 85%
- alert: JvmHeapHigh
expr: |
jvm_memory_used_bytes{area="heap"}
/ jvm_memory_max_bytes{area="heap"} > 0.85
for: 5m
labels:
severity: warning
SLI / SLO / SLA
| 概念 | 全称 | 说明 | 示例 |
|---|---|---|---|
| SLI | Service Level Indicator | 服务质量指标 | 请求成功率、P99 延迟 |
| SLO | Service Level Objective | 服务质量目标 | 成功率 ≥ 99.95% |
| SLA | Service Level Agreement | 服务等级协议 | 可用性 99.9%,违约赔偿 |
SLO 示例
可用性 SLO:99.95%
→ 每月最多不可用 21.6 分钟
→ 错误预算(Error Budget)= 0.05%
延迟 SLO:
P50 < 100ms
P99 < 500ms
告警分级与处理
| 级别 | 含义 | 通知方式 | 响应时间 |
|---|---|---|---|
| P0 | 核心链路中断 | 电话 + 短信 + 群消息 | 5 分钟 |
| P1 | 功能严重降级 | 短信 + 群消息 | 15 分钟 |
| P2 | 局部异常 | 群消息 | 1 小时 |
| P3 | 观察项 | 邮件 / 看板 | 下个工作日 |
告警要注意的问题
- 告警风暴:短时间大量告警,需做合并与抑制(AlertManager
group_by、inhibit_rules) - 告警疲劳:告警太多导致忽视,要做好分级和收敛
- 误告警:阈值设置不合理,需持续调优
常见面试问题
Q1: Prometheus 的拉(Pull)模式和推(Push)模式有什么区别?
答案:
- Pull:Prometheus 主动拉取目标
/metrics,适合服务发现场景 - Push:通过 Pushgateway 推送指标,适合短生命周期任务(批处理 Job)
- 拉模式优点:能感知目标是否存活,不依赖目标主动上报
Q2: 如何监控 JVM 关键指标?
答案:
| 指标 | 说明 | 告警阈值建议 |
|---|---|---|
| 堆内存使用率 | jvm_memory_used_bytes{area="heap"} | > 85% |
| Full GC 次数 | jvm_gc_pause_seconds_count{action="major"} | 每分钟 > 1 次 |
| 线程数 | jvm_threads_live_threads | 持续增长 |
| 类加载数 | jvm_classes_loaded_classes | 持续增长(可能类加载泄漏) |
Q3: 链路追踪和监控指标的区别?
答案:
- Metrics(指标):聚合数据,回答"系统整体状态如何"
- Tracing(链路追踪):单次请求全链路,回答"这个请求为什么慢"
- Logging(日志):具体事件记录,回答"发生了什么"
三者互补,合称可观测性(Observability)三大支柱。具体实现可参考 链路追踪。
Q4: 如何设计业务监控大盘?
答案:
核心指标看板:
- 全局概览:QPS、RT、错误率、成功率
- 核心链路:下单成功率、支付成功率、库存扣减耗时
- 资源水位:CPU、内存、连接池、MQ 积压
- 对比:环比(vs 昨天同时段)、同比(vs 上周同时段)