Prometheus 监控 Kafka 全栈实战:从吞吐量到消费者延迟的实时可观测性
Apache Kafka 是现代数据管道的核心枢纽,它的Broker 吞吐量、网络请求延迟、分区副本状态、ISR 收缩以及最重要的消费者 Lag,直接决定数据流的可靠性与实时性。Prometheus 通过JMX Exporter与kafka_exporter双剑合璧,可将 Kafka 的所有 JVM、Broker 指标及消费者组偏移信息转化为标准化时序数据。本文将带你从零配置 JMX 代理与专用导出器,构建覆盖生产者、Broker 到消费者的全链路监控。
1. 方案选型:JMX Exporter + kafka_exporter 组合
| 组件 | 负责范围 | 关键指标 |
|---|---|---|
| JMX Exporter(随 Broker 启动) | Broker 运行时状态、JVM、网络、请求队列 | 消息入站速率、分区数量、ISR 状态、请求延迟、JVM GC |
| kafka_exporter(独立进程) | 消费者组偏移、分区 Lag、Topic/Partition 详情 | kafka_consumergroup_lag、kafka_topic_partitions |
| Cruise Control 或 CMAK | 集群负载均衡、副本迁移 | 不直接暴露 Prometheus 指标,可配合 JMX 采集 |
最佳实践是每个 Broker 加载 JMX Exporter,并额外部署一个
kafka_exporter抓取消群体偏移,两个 Job 在 Prometheus 中合并展现。
2. JMX Exporter 监控 Broker
2.1 下载并配置 JMX 代理
在每个 Broker 服务器上下载jmx_prometheus_javaagent:
wgethttps://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.20.0/jmx_prometheus_javaagent-0.20.0.jarsudomkdir/etc/kafka/prometheussudomvjmx_prometheus_javaagent-0.20.0.jar /etc/kafka/prometheus/编写规则文件/etc/kafka/prometheus/kafka_jmx.yml,覆盖核心 Kafka MBean:
startDelaySeconds:0hostPort:127.0.0.1:9999# Kafka 默认 JMX 端口ssl:falserules:# 消息流入/流出速率-pattern:"kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>(Count|OneMinuteRate)"name:kafka_messages_in_per_sec_$1-pattern:"kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec><>(Count|OneMinuteRate)"name:kafka_bytes_in_per_sec_$1-pattern:"kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec><>(Count|OneMinuteRate)"name:kafka_bytes_out_per_sec_$1# 分区与副本-pattern:"kafka.server<type=ReplicaManager, name=UnderReplicatedPartitions><>(Value)"name:kafka_under_replicated_partitions-pattern:"kafka.server<type=ReplicaManager, name=PartitionCount><>(Value)"name:kafka_partition_count-pattern:"kafka.server<type=ReplicaManager, name=OfflineReplicaCount><>(Value)"name:kafka_offline_replica_count-pattern:"kafka.server<type=ReplicaManager, name=IsrShrinksPerSec><>(Count)"name:kafka_isr_shrinks_per_sec_count# 网络请求-pattern:"kafka.network<type=RequestMetrics, name=RequestsPerSec, request=(.*)><>(Count)"name:kafka_requests_per_sec_$1-pattern:"kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(.*)><>(Count|Mean)"name:kafka_request_total_time_ms_$2labels:request:$1# 磁盘与日志-pattern:"kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>(Count|Mean)"name:kafka_log_flush_rate_and_time_ms_$1# JVM 内存与 GC-pattern:"java.lang<type=Memory><HeapMemoryUsage>(used|max)"name:jvm_memory_heap_$1-pattern:"java.lang<type=GarbageCollector, name=(.+)><>(CollectionCount|CollectionTime)"name:jvm_gc_$1_$22.2 启用 JMX 并加载代理
修改 Kafka 的bin/kafka-server-start.sh或systemd环境变量,设置 JMX 端口并添加 Java agent:
exportKAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"exportKAFKA_OPTS="$KAFKA_OPTS-javaagent:/etc/kafka/prometheus/jmx_prometheus_javaagent-0.20.0.jar=9097:/etc/kafka/prometheus/kafka_jmx.yml"监听端口9097提供 Prometheus 指标。重启 Broker,验证curl http://localhost:9097/metrics。
3. 部署 kafka_exporter 监控消费延迟
danielqsj/kafka_exporter连接 Kafka 集群并读取__consumer_offsets,生成消费者组 Lag 指标。
Docker 运行:
dockerrun-d\--namekafka_exporter\-p9308:9308\danielqsj/kafka-exporter:v1.7.0\--kafka.server=kafka1:9092\--kafka.server=kafka2:9092\--kafka.version=2.8.0二进制:
wgethttps://github.com/danielqsj/kafka_exporter/releases/download/v1.7.0/kafka_exporter-1.7.0.linux-amd64.tar.gztarxzf kafka_exporter-1.7.0.linux-amd64.tar.gz ./kafka_exporter--kafka.server=localhost:9092 --web.listen-address=:9308访问http://localhost:9308/metrics,得到kafka_consumergroup_lag等指标。
4. 配置 Prometheus 抓取
scrape_configs:-job_name:'kafka-brokers'scrape_interval:30sstatic_configs:-targets:-'broker1:9097'-'broker2:9097'-'broker3:9097'labels:cluster:'kafka-prod'-job_name:'kafka-consumers'scrape_interval:60sstatic_configs:-targets:['kafka-exporter:9308']labels:cluster:'kafka-prod'5. 核心监控指标与 PromQL
| 维度 | 关键指标 (来源) | 含义 | PromQL 示例 |
|---|---|---|---|
| Broker 存活 | up{job="kafka-brokers"} | 1 = 可达 | 直接告警 |
| 消息吞吐 | kafka_bytes_in_per_sec_OneMinuteRate(JMX) | 入站字节速率 | rate(kafka_bytes_in_per_sec_Count[1m]) |
| 分区状态 | kafka_under_replicated_partitions(JMX) | 副本不足的分区数 | > 0 立即告警 |
| 离线分区 | kafka_offline_replica_count(JMX) | 离线副本数 | > 0 即严重 |
| 活跃控制器 | kafka_controller_active_count(JMX 某些版本) | 控制器数量 | 应为 1 |
| 请求延迟 | kafka_request_total_time_ms_Mean{request="Produce"}(JMX) | 请求平均耗时 | > 100ms 需关注 |
| 消费者 Lag | kafka_consumergroup_lag(kafka_exporter) | 消费者滞后消息数 | kafka_consumergroup_lag > 10000 |
| Lag 总和 | sum(kafka_consumergroup_lag) by (consumergroup) | 按消费者组聚合 | 趋势告警 |
| JVM 堆内存 | jvm_memory_heap_used / jvm_memory_heap_max | 堆使用率 | > 80% 告警 |
| GC 时间 | rate(jvm_gc_G1_Young_Generation_CollectionTime[5m]) | GC 耗时速率 | 高则 JVM 压力大 |
常用计算:
- 生产吞吐量 (MB/s):
rate(kafka_bytes_in_per_sec_Count[1m]) / 1024 / 1024 - 消费延迟(条):
kafka_consumergroup_lag
6. Grafana 仪表盘推荐
- Kafka Broker Exporter:Dashboard ID7589(经典全面,基于 JMX Exporter 指标),展示 Broker 吞吐、请求、分区、JVM。
- Kafka Consumer Lag:ID7628(基于 kafka_exporter),显示消费者组 Lag 详情。
- Kafka Overview (Kubernetes):若在 K8s 运行,可导入 ID13296。
导入后,选择数据源并将cluster变量绑定到你的 Kafka 集群。
7. 告警规则实战
groups:-name:kafka_alertsrules:-alert:KafkaBrokerDownexpr:up{job="kafka-brokers"}== 0for:1mlabels:severity:criticalannotations:summary:"Kafka Broker {{ $labels.instance }} 下线"-alert:KafkaUnderReplicatedPartitionsexpr:kafka_under_replicated_partitions>0for:5mlabels:severity:criticalannotations:summary:"存在未充分复制的分区,总数:{{ $value }}"-alert:KafkaOfflineReplicaexpr:kafka_offline_replica_count>0for:1mlabels:severity:criticalannotations:summary:"Kafka 离线副本数大于 0,可能丢失数据"-alert:KafkaHighConsumerLagexpr:kafka_consumergroup_lag>10000for:10mlabels:severity:warningannotations:summary:"消费者组 {{ $labels.consumergroup }} Lag 超过 10000"-alert:KafkaHighProduceLatencyexpr:kafka_request_total_time_ms_Mean{request="Produce"}>100for:5mlabels:severity:warningannotations:summary:"生产请求平均延迟超过 100ms"-alert:KafkaJvmHeapUsageexpr:(jvm_memory_heap_used / jvm_memory_heap_max)>0.85for:10mlabels:severity:warningannotations:summary:"Broker {{ $labels.instance }} 堆内存使用率超过 85%"8. 进阶:安全认证与多集群
8.1 SASL/SSL 认证
若 Kafka 启用了 SASL_SSL,JMX 连接不受影响(本地 JMX),但kafka_exporter需要提供安全参数:
kafka_exporter\--kafka.server=broker:9093\--tls.enabled\--tls.ca-file=/path/ca-cert\--sasl.enabled\--sasl.mechanism=scram-sha256\--sasl.username=prometheus\--sasl.password=passwordJMX Exporter 的 YAML 中可以配置username和password若 JMX 远程认证开启,但通常 JMX 仅本地访问。
8.2 Kafka 多集群
在每个集群部署独立的kafka_exporter,并在 Prometheus 中使用不同的cluster标签区分。对于 Broker JMX,也可分组抓取。
8.3 使用 Prometheus Operator (Kubernetes)
若 Kafka 通过 Strimzi 或 Confluent Operator 部署,它们已内置 Prometheus 指标暴露(Strimzi 直接暴露metrics端口),只需创建PodMonitor即可。
9. 性能与安全建议
- JMX Exporter 随 Broker 启动,内存开销极小(< 50MB)。
kafka_exporter会扫描所有消费者组偏移,在大型集群(> 1000 个分区)中建议将scrape_interval设为 60s 或更久,且使用--kafka.consumer-groups-regex过滤不必要的组。- 防火墙仅允许 Prometheus 访问 9097 和 9308 端口。
至此,你的 Kafka 集群从 Broker 的 JVM 健康、网络吞吐、到消费者的积压情况,全部纳入了 Prometheus 的统一监控体系。任何副本丢失、分区离线或消费延迟都将在第一时间触发告警,让数据管道真正实现端到端的可观测性,为实时分析、事件驱动的业务提供坚实底座。