7.0 KiB
tags, create time
| tags | create time | ||||
|---|---|---|---|---|---|
|
2026-05-24 19:52 |
MQ 监控指标与告警
概述
消息队列作为系统间的"黑盒"中间件,一旦出问题往往影响全局。本文梳理 MQ 监控的核心指标体系,涵盖 Broker、Producer、Consumer 三个维度,并介绍基于 Prometheus + Grafana 的监控告警实践。
正文
为什么 MQ 需要专门的监控
消息队列不像 Web 服务那样有直观的 HTTP 状态码,它的健康状况藏在各种内部指标里。一个 Topic 的消费延迟可能已经到了几小时,但表面上看 Producer 和 Consumer 都在正常运行——只是 Consumer 跟不上了。等到下游业务发现数据不一致时,往往已经积重难返。
MQ 监控的核心目标就三个字:看得见。看得见消息有没有堆积,看得见 Broker 有没有过载,看得见消费者有没有掉队。
Broker 核心指标
| 指标 | 含义 | 关注点 |
|---|---|---|
| 消息入队速率 (MessagesIn/s) | 每秒写入的消息数 | 突增可能表示上游流量异常 |
| 消息出队速率 (BytesOut/s) | 每秒读出的字节数 | 与入队速率对比判断消费是否跟得上 |
| 磁盘使用率 | 日志段占用的磁盘空间 | 超过 80% 就该警惕 |
| 网络 IO | 网卡吞吐量 | 高负载时容易成为瓶颈 |
| 连接数 | 当前活跃的客户端连接 | 突增可能是连接泄漏 |
| ISR 数量 | In-Sync Replicas 数量 | ISR 收缩意味着有 Follower 掉队 |
[!question] ISR(In-Sync Replicas)数量减少时,消息的可靠性会受到什么影响?如果你设置了
acks=all,ISR 缩减到 1 会发生什么?
Producer 核心指标
Producer 侧最需要关注的是发送成功率和发送延迟。
- 发送成功率:失败的发送请求占比。如果持续有失败,说明 Broker 端有问题(磁盘满、网络分区)。
- 发送延迟 P99:99 分位的发送耗时。正常情况下应该在毫秒级,如果飙升到秒级,说明 Broker 压力过大或者网络抖动。
- 重试率:发送失败后重试的比例。高重试率意味着消息可能乱序(Kafka 中同一 Partition 内的消息顺序靠 offset 保证,但重试可能导致后发的消息先到)。
- 批大小(Batch Size):Producer 端的批量发送大小。批越大吞吐越高,但延迟也越大。
Consumer 核心指标
Consumer 侧最核心的指标是 Consumer Lag——消费者当前的消费位置与最新消息之间的差距。
Lag 本质上衡量的是"消费者落后了多远"。如果 Lag 持续增长,说明消费者处理不过来,消息正在积压。
- 消费速率:每秒处理的消息数,应与 Producer 的入队速率基本持平。
- Rebalance 次数:Consumer Group 发生 Rebalance 的频率。频繁 Rebalance 会导致消费暂停,通常是 Consumer 不稳定(频繁重启、处理超时)引起的。
- 处理耗时:单条消息从业务处理的平均耗时。如果处理耗时接近
max.poll.interval.ms,就有触发 Rebalance 的风险。
Prometheus + Grafana 监控搭建
监控架构分四层:
graph LR
MQ["MQ Cluster"] -->|"指标暴露"| Exporter["MQ Exporter"]
Exporter -->|"pull /metrics"| Prometheus["Prometheus"]
Prometheus -->|"查询"| Grafana["Grafana"]
Prometheus -->|"告警规则"| AlertManager["AlertManager"]
AlertManager -->|"通知"| Notify["DingTalk / PagerDuty"]
Exporter 配置:Kafka 可以用 kafka_exporter 或 JMX Exporter 暴露指标。kafka_exporter 轻量级,适合快速接入;JMX Exporter 功能更全,但配置更复杂。
# Prometheus 配置示例
scrape_configs:
- job_name: "kafka"
static_configs:
- targets: ["kafka-exporter:9308"]
scrape_interval: 15s
核心 Dashboard 设计:一个实用的 MQ Dashboard 通常包含以下几个面板:
- 总览面板:集群消息入队/出队速率、总 Lag 数、Broker 存活数。
- Broker 面板:每个 Broker 的磁盘使用率、网络 IO、ISR 数量、请求队列深度。
- Topic 面板:每个 Topic 的消息速率、Partition 分布、Lag 趋势。
- Consumer Group 面板:每个 Group 的 Lag、消费速率、Rebalance 次数。
告警策略
好的告警策略不是"什么都报",而是"报了就要行动"。三种常用的告警模型:
基于阈值:最直观,比如 Consumer Lag > 10000 触发告警。适合有明确 SLO 的场景。
基于趋势:Lag 的绝对值不重要,重要的是它是否在持续增长。比如"Lag 连续 10 分钟单调递增"就该告警,即使当前 Lag 只有 100。
基于异常检测:用统计方法检测指标是否偏离正常范围。比如消费速率突然降到 0,但 Producer 侧没有任何变化,这很可能是 Consumer 挂了。
[!question] 你能设计一个既不会频繁误报、又不会漏报关键问题的 Consumer Lag 告警规则吗?阈值设多少合适?
Go 代码示例:自定义 Consumer Lag 监控
package main
import (
"context"
"log"
"net/http"
"time"
"github.com/IBM/sarama"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
// consumerLag 每个 Partition 的消费延迟
consumerLag = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "myapp_consumer_lag",
Help: "Consumer lag per partition",
},
[]string{"topic", "partition", "group"},
)
)
func init() {
prometheus.MustRegister(consumerLag)
}
// collectLag 定期采集 Consumer Lag 并暴露给 Prometheus
func collectLag(brokers []string, group, topic string) {
config := sarama.NewConfig()
client, err := sarama.NewClient(brokers, config)
if err != nil {
log.Fatalf("create client: %v", err)
}
defer client.Close()
ticker := time.NewTicker(10 * time.Second)
for range ticker.C {
partitions, _ := client.Partitions(topic)
for _, p := range partitions {
// 获取最新 offset
newest, _ := client.GetOffset(topic, p, sarama.OffsetNewest)
// 获取消费者组当前 offset(实际需通过 Admin API)
// 这里简化为从外部获取
groupOffset := getGroupOffset(group, topic, p)
lag := float64(newest - groupOffset)
consumerLag.WithLabelValues(topic,
string(rune(p+'0')), group).Set(lag)
}
}
}
func getGroupOffset(group, topic string, partition int32) int64 {
// 实际实现中通过 Kafka Admin API 获取
return 0
}
func main() {
go collectLag([]string{"localhost:9092"}, "my-group", "orders")
http.Handle("/metrics", promhttp.Handler())
log.Println("metrics server on :2112")
log.Fatal(http.ListenAndServe(":2112", nil))
}
这段代码通过 Sarama 客户端定期查询每个 Partition 的最新 offset 和消费者组当前 offset,计算差值作为 Lag,然后通过 Prometheus Gauge 暴露。Grafana 中可以直接用 myapp_consumer_lag 指标配置 Dashboard 和告警规则。