4. 监控体系搭建:JMX指标采集、Prometheus+Grafana看板设计、关键指标(BytesIn/Out、TotalFetchRequestsPerSec)

Kafka 堆积诊断的前提是“可观测”。没有实时、准确的监控数据,堆积治理就是盲人摸象。本章聚焦于搭建一套生产级的 Kafka 监控体系,覆盖从 JMX 指标暴露、Prometheus 采集到 Grafana 看板设计的完整链路,并深度解析 BytesIn/Out、TotalFetchRequestsPerSec 等核心指标在堆积场景下的判读方法。

4.1 监控架构总览

下图展示了从 Kafka Broker 到最终可视化看板的完整数据流。JMX 作为指标源,由 JMX Exporter 转换为 Prometheus 格式,Prometheus Server 定期拉取并存储,Grafana 通过 PromQL 查询渲染看板。

Kafka 监控体系数据流架构 Kafka 监控体系数据流架构 Kafka Broker JMX MBeans JMX Exporter HTTP /metrics Prometheus TSDB Grafana Dashboard 说明: 1. Kafka Broker 通过 JMX 暴露 MBeans,包括 BytesInPerSec、BytesOutPerSec、TotalFetchRequestsPerSec 等。 2. JMX Exporter 以 Java Agent 方式嵌入 Broker 进程,将 JMX 指标转换为 Prometheus 格式的 /metrics 端点。 3. Prometheus Server 定期拉取(scrape)Exporter 数据,存入本地 TSDB。 4. Grafana 通过 Prometheus 数据源查询 PromQL,渲染实时看板。

4.2 JMX 指标采集:从 Broker 到 Exporter

Kafka 原生使用 JMX(Java Management Extensions)暴露运行时指标。每个 Broker 启动时都会注册一组标准 MBean,涵盖网络、请求、日志、分区等多个维度。

4.2.1 关键 JMX MBean 路径

指标类别 MBean ObjectName 关键属性 堆积诊断用途
网络入站 kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec Count, MeanRate, OneMinuteRate 判断生产端写入速率是否突降
网络出站 kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec Count, MeanRate, OneMinuteRate 判断消费端拉取速率是否跟不上生产
拉取请求 kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec Count, MeanRate 反映消费者拉取频率,堆积时通常下降
生产请求 kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec Count, MeanRate 反映生产者请求量,与堆积正相关
日志大小 kafka.log:type=Log,name=Size,partition=* Value 分区日志大小持续增长说明堆积

4.2.2 JMX Exporter 部署配置

推荐使用 prometheus/jmx_exporter 作为 Java Agent 附加到 Kafka Broker 进程。以下是一个最小化配置示例:

# jmx_exporter_config.yml
startDelaySeconds: 0
ssl: false
rules:
  # 捕获 BytesInPerSec 指标
  - pattern: "kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec><>OneMinuteRate"
    name: "kafka_broker_bytes_in_per_sec"
    type: GAUGE
    labels:
      broker: "$1"
  # 捕获 BytesOutPerSec 指标
  - pattern: "kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec><>OneMinuteRate"
    name: "kafka_broker_bytes_out_per_sec"
    type: GAUGE
    labels:
      broker: "$1"
  # 捕获 TotalFetchRequestsPerSec
  - pattern: "kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec><>OneMinuteRate"
    name: "kafka_broker_fetch_requests_per_sec"
    type: GAUGE
    labels:
      broker: "$1"

启动 Broker 时添加 JVM 参数:

KAFKA_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent.jar=8080:/opt/jmx_exporter/jmx_exporter_config.yml" \
./bin/kafka-server-start.sh config/server.properties
最佳实践: 建议将 JMX Exporter 的监听端口(如 8080)与 Kafka 服务端口分开,避免端口冲突。同时,在 Prometheus 的 scrape_config 中为该端口配置独立的 scrape_interval,通常设为 15s 即可满足堆积诊断的精度要求。

4.3 Prometheus 采集配置

在 Prometheus 的 prometheus.yml 中添加 Kafka Broker 的抓取目标。如果集群有多个 Broker,建议使用服务发现或静态配置列表。

# prometheus.yml 片段
scrape_configs:
  - job_name: 'kafka-broker'
    static_configs:
      - targets:
        - 'broker1.example.com:8080'
        - 'broker2.example.com:8080'
        - 'broker3.example.com:8080'
    metrics_path: '/metrics'
    scrape_interval: 15s
    scrape_timeout: 10s
注意: 如果 Broker 数量较多(超过 10 台),建议将 scrape_interval 调整为 30s,避免 Prometheus 抓取压力过大导致指标丢失。堆积诊断场景下,15s 的粒度通常足够捕捉分钟级的堆积变化。

4.4 Grafana 看板设计:堆积诊断视图

Grafana 看板是监控数据的最终呈现层。针对堆积诊断,我们设计三个核心面板:流量对比面板、请求速率面板、堆积趋势面板。

4.4.1 流量对比面板(BytesIn vs BytesOut)

该面板使用时间序列图,同时展示 BytesInPerSec 和 BytesOutPerSec 的 1 分钟速率。当 BytesIn 持续高于 BytesOut 时,说明消费端处理能力不足,堆积正在形成。

# PromQL 示例:BytesIn 与 BytesOut 对比
# BytesIn 1分钟速率
rate(kafka_broker_bytes_in_per_sec[1m])
# BytesOut 1分钟速率
rate(kafka_broker_bytes_out_per_sec[1m])

4.4.2 请求速率面板(TotalFetchRequestsPerSec)

TotalFetchRequestsPerSec 反映消费者拉取请求的频率。堆积发生时,如果该指标下降,说明消费者可能被阻塞或已停止拉取;如果该指标维持高位但 BytesOut 很低,说明消费者在频繁拉取但每次拉取的数据量很小(可能因为消息体过大或网络瓶颈)。

# PromQL 示例:Fetch 请求速率
rate(kafka_broker_fetch_requests_per_sec[1m])

4.4.3 堆积趋势面板(日志大小变化)

通过监控特定分区的日志大小(Log Size)变化,可以直接判断堆积是否在增长。建议按 Topic 分组聚合。

# PromQL 示例:按 Topic 聚合日志大小
sum by(topic) (kafka_log_log_size{topic=~".+"})
Grafana 堆积诊断看板布局 Grafana 堆积诊断看板布局示意 流量对比面板 BytesInPerSec (蓝线) BytesOutPerSec (绿线) 堆积判据:BytesIn > BytesOut 持续 5 分钟 请求速率面板 TotalFetchRequestsPerSec TotalProduceRequestsPerSec 堆积判据:Fetch 速率下降 + Produce 速率上升 堆积趋势面板 按 Topic 聚合日志大小 堆积判据:日志大小持续线性增长 告警状态面板 堆积告警规则触发状态 当前堆积 Topic 列表

4.5 关键指标深度解析:堆积场景下的判读

以下表格总结了在堆积发生时,三个核心指标的典型表现模式:

指标 正常状态 堆积初期 堆积严重 恢复阶段
BytesInPerSec 稳定波动,与业务流量一致 维持高位或上升 可能因背压下降 恢复至正常水平
BytesOutPerSec 与 BytesIn 基本持平 开始低于 BytesIn 明显低于 BytesIn,甚至趋近于 0 逐步回升,追赶 BytesIn
TotalFetchRequestsPerSec 稳定,与消费者数量正相关 可能不变或略降 显著下降,消费者被阻塞 恢复至正常频率
实战案例: 某金融业务 Kafka 集群出现堆积告警。通过 Grafana 看板发现 BytesInPerSec 维持在 50 MB/s,而 BytesOutPerSec 从 48 MB/s 骤降至 12 MB/s,同时 TotalFetchRequestsPerSec 从 200 req/s 降至 30 req/s。排查发现消费者端数据库连接池耗尽,导致消费线程阻塞。修复连接池后,BytesOut 和 Fetch 请求速率逐步恢复,堆积在 10 分钟内消解。

4.6 告警规则设计

基于上述指标,可以设计以下 Prometheus 告警规则,实现堆积的自动检测:

# kafka_alerts.yml
groups:
  - name: kafka_lag_alerts
    rules:
      # 规则1:BytesOut 远低于 BytesIn 持续 5 分钟
      - alert: KafkaBytesOutLagging
        expr: |
          rate(kafka_broker_bytes_in_per_sec[5m])
          /
          rate(kafka_broker_bytes_out_per_sec[5m]) > 1.5
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Kafka BytesOut 落后 BytesIn 超过 50%"
          description: "Broker {{ $labels.instance }} BytesIn/BytesOut 比值 > 1.5,持续 5 分钟"

      # 规则2:Fetch 请求速率下降超过 30%
      - alert: KafkaFetchRequestsDropping
        expr: |
          rate(kafka_broker_fetch_requests_per_sec[5m])
          /
          avg_over_time(rate(kafka_broker_fetch_requests_per_sec[1h])[1h:]) < 0.7
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Kafka Fetch 请求速率异常下降"
          description: "当前 Fetch 速率低于过去 1 小时平均值的 70%"

4.7 本章小结

一套完整的 Kafka 监控体系是堆积诊断的基石。通过 JMX Exporter 暴露指标、Prometheus 统一采集、Grafana 可视化看板,运维人员可以实时掌握 BytesIn/Out 和 TotalFetchRequestsPerSec 等关键指标的变化。当 BytesIn 持续高于 BytesOut、Fetch 请求速率异常下降时,即可快速定位堆积风险,为后续的 API 治理和性能调优提供数据支撑。