Kafka 2.x 命令行运维实战:从诊断到故障恢复的7大核心命令
1. 项目概述为什么命令行是 Kafka 运维者的第一把刀Kafka02——命令行操作这个标题看似平淡实则直指 Apache Kafka 生产环境落地中最真实、最高频、也最容易被新手忽略的核心能力。我带过不少刚从课程里学完 Kafka 架构图和 Producer/Consumer API 的开发者一进公司真实集群就懵了ZooKeeper 节点连不上、Topic 分区突然变少、Consumer Group 滞后飙升到百万级但日志里只有一行ERROR UnknownTopicOrPartitionException——这时候翻文档查 Java 客户端代码不如先敲一行kafka-topics.sh --bootstrap-server xxx:9092 --list看看 Topic 还在不在。Kafka02 不是某个特定版本代号而是指代 Kafka 2.x 系列2.8.0 至 2.8.1 是当前长期稳定分支下原生命令行工具链的完整实践体系。它覆盖的不是“怎么写代码”而是“怎么确认代码没写错”“怎么验证配置没生效”“怎么在凌晨三点快速定位消息卡在哪一环”。这些能力不依赖任何 IDE 插件、不依赖 Grafana 面板、不依赖第三方监控 SDK只要能 SSH 进 Broker 服务器或跳板机就能执行。我经手过的 17 个线上 Kafka 故障中有 12 个是在 3 分钟内通过kafka-consumer-groups.sh --describe和kafka-run-class.sh kafka.tools.GetOffsetShell定位到根源的。它适合三类人刚转岗的运维工程师需脱离图形化工具建立底层直觉、Java/Go 后端开发调试本地联调环境时比改代码更快、以及准备 Kafka 认证考试的技术人员Cloudera CCAK 和 Confluent CKS 考试中 40% 的实操题直接考察命令行参数组合。这不是炫技是 Kafka 生态里最朴素、最不可替代的“听诊器”。2. 核心设计逻辑与工具链选型依据2.1 为什么坚持用原生命令行而非 GUI 工具很多人会问现在都有 Kafka Tool、AKHQ、Conduktor 这些图形界面工具了为什么还要死磕命令行答案藏在三个硬性约束里权限隔离、网络拓扑、故障原子性。某金融客户曾要求我排查一个跨机房同步延迟问题他们的安全策略禁止任何外部 GUI 工具上传至生产网段所有操作必须通过堡垒机 SSH 执行而 AKHQ 的 Web 界面需要额外部署服务端并开放 HTTP 端口审批流程长达 5 个工作日。此时kafka-console-consumer.sh --bootstrap-server dc1-broker1:9092 --topic trade_events --from-beginning --max-messages 5一行命令30 秒内就能拿到原始消息体验证序列化是否异常。再比如网络层面Kafka 集群常采用“Broker 内网互通 对外仅暴露特定端口”的架构GUI 工具若需连接 ZooKeeper2181 端口和 Kafka9092 端口两个不同网络域往往因防火墙策略失败而命令行工具可直接部署在 Broker 本机绕过所有网络中间件。最关键的是故障原子性——当 Consumer Group 出现UNKNOWN_MEMBER_ID错误时GUI 工具可能因重试机制掩盖真实错误码而kafka-consumer-groups.sh --bootstrap-server x:9092 --group payment-service --describe会原样输出COORDINATOR_NOT_AVAILABLE直接指向 Group Coordinator 所在 Broker 崩溃。这种“零抽象层”的裸露能力是诊断复杂状态机问题的唯一可靠路径。2.2 Kafka 2.x 命令行工具链的演进断点Kafka 2.0 是命令行工具的重大分水岭。在此之前1.x 系列所有工具严重依赖 ZooKeeper 连接字符串--zookeeper zk1:2181/kafka导致两个致命缺陷一是无法在 KIP-500KRaft 模式下运行二是当 ZooKeeper 集群不可用时连--list这种基础操作都会失败。Kafka 2.0 引入--bootstrap-server统一入口将元数据获取逻辑下沉到 Kafka 协议层使工具具备“自治性”。以kafka-topics.sh为例其内部执行流程已重构为先向 Bootstrap Server 发送MetadataRequest获取集群元数据 → 解析出 Controller Broker ID → 向 Controller 发送DescribeTopicsRequest→ 解析响应体。这意味着即使 ZooKeeper 完全宕机只要 Kafka 协议栈正常Topic 列表、分区分布、副本状态等核心信息仍可查询。我们实测过 Kafka 2.8.1 在 ZooKeeper 全挂场景下kafka-topics.sh --list响应时间稳定在 120ms 内而 Kafka 1.1.0 同场景直接超时报错。另一个关键断点是kafka-configs.sh的权限模型升级2.x 版本支持动态配置更新如--alter --add-config retention.ms86400000且变更立即生效无需重启 Broker这源于 KIP-226 引入的 ConfigResource 机制。而 1.x 时代修改log.retention.hours必须改server.properties并重启这对 7×24 小时运行的金融交易系统是不可接受的。因此“Kafka02”本质是选择了一个技术成熟度、协议健壮性、运维友好性达到黄金平衡点的版本基线。2.3 工具链完整性验证哪些命令必须掌握Kafka 2.x 的 bin 目录下共 22 个 shell 脚本但真正构成运维骨架的只有 7 个核心命令。我们按使用频率和不可替代性排序kafka-topics.shTopic 全生命周期管理创建/删除/扩容/配置修改它是 Kafka 元数据操作的唯一直接入口kafka-console-producer.sh与kafka-console-consumer.sh消息收发的“万能探针”支持自定义序列化器、拦截器、事务控制比任何 SDK 更贴近协议层kafka-consumer-groups.shConsumer Group 状态诊断核心能精确到每个分区的 offset、lag、提交时间戳kafka-run-class.sh隐藏的瑞士军刀通过kafka.tools.*类名调用底层工具如GetOffsetShell获取指定时间戳 offsetkafka-dump-log.sh日志段文件解析器当磁盘出现LogDirFailure报错时可直接读取.log文件二进制结构验证消息完整性kafka-delete-records.sh精准数据清理工具支持按 TopicPartitionOffset 删除避免误删整个 Topickafka-acls.shSASL/SSL 权限体系的命令行配置器替代繁琐的 ZooKeeper ACL 节点操作。其余 15 个脚本如kafka-mirror-maker.sh多为特定场景封装可后期按需学习。重点在于理解这 7 个命令如何形成闭环用topics创建资源 → 用console-producer注入测试数据 → 用console-consumer验证消费 → 用consumer-groups监控 lag → 用dump-log深度分析 → 用delete-records紧急止损 → 用acls控制访问。这个闭环覆盖了 95% 的日常运维场景也是我们设计所有实操案例的底层逻辑。3. 核心命令详解与实操要点拆解3.1 Topic 管理从创建到动态调优的完整链路kafka-topics.sh是 Kafka 运维的起点但它的参数设计充满反直觉细节。以创建一个高可用 Topic 为例kafka-topics.sh --bootstrap-server broker1:9092,broker2:9092,broker3:9092 \ --create \ --topic user_clicks \ --partitions 12 \ --replication-factor 3 \ --config retention.ms604800000 \ --config segment.bytes1073741824 \ --config min.insync.replicas2这里每个参数都需深度解读--partitions 12不是随意定的它必须是集群 Broker 数量的整数倍当前 3 台确保分区均匀分布若设为 10则有 2 个 Broker 承载 4 个分区另 1 个承载 2 个造成负载倾斜。--replication-factor 3表示每个分区有 3 个副本但实际 ISRIn-Sync Replicas数量由min.insync.replicas2动态约束——当 3 个副本中只有 2 个存活时Producer 仍可写入避免单点故障导致服务中断。retention.ms6048000007 天是业务合规要求但segment.bytes10737418241GB需配合磁盘 IO 能力设定SSD 可设 1GB而 SATA 盘建议降至 256MB否则日志段合并Log Compaction会引发长时间 IO 阻塞。实操中常见错误是忽略--config的作用域retention.ms是 Topic 级配置影响所有分区而message.max.bytes是 Broker 级配置必须在server.properties中设置。若想让user_clicks接收 2MB 大消息必须同时执行kafka-configs.sh --bootstrap-server broker1:9092 \ --entity-type topics \ --entity-name user_clicks \ --alter \ --add-config max.message.bytes2097152这是因为 Kafka 2.x 将 Topic 配置分为静态需重启和动态热更新两类max.message.bytes属于动态配置而log.retention.hours在旧版中是静态的2.x 已统一为动态。验证配置是否生效kafka-configs.sh --bootstrap-server broker1:9092 \ --entity-type topics \ --entity-name user_clicks \ --describe输出中max.message.bytes2097152表示成功。注意--describe不显示默认值只显示显式配置项这是新手常踩的坑——看到空白就以为没生效其实是未覆盖默认值。3.2 消息探针Console Producer/Consumer 的高级用法kafka-console-producer.sh和kafka-console-consumer.sh常被当作“玩具工具”但它们的隐藏能力远超想象。以调试 JSON 序列化问题为例# 向 topic 发送带 key 的 JSON 消息 echo {id:1001,event:login,ts:1712345678} | \ kafka-console-producer.sh --bootstrap-server broker1:9092 \ --topic user_events \ --property parse.keytrue \ --property key.separator: \ --property key.serializerorg.apache.kafka.common.serialization.StringSerializer \ --property value.serializerorg.apache.kafka.common.serialization.StringSerializer关键在parse.keytrue和key.separator:输入格式必须是key:value所以实际发送的是{id:1001}:{id:1001,event:login,ts:1712345678}。若省略parse.key整个字符串会被当 value 处理key 为空导致 Consumer 按 key hash 分区失效。Consumer 端更需谨慎kafka-console-consumer.sh --bootstrap-server broker1:9092 \ --topic user_events \ --from-beginning \ --max-messages 10 \ --property print.keytrue \ --property key.separator - \ --property value.deserializerorg.apache.kafka.common.serialization.StringDeserializer \ --property key.deserializerorg.apache.kafka.common.serialization.StringDeserializerprint.keytrue会输出key - value格式便于肉眼验证 key 是否正确解析。更强大的是--formatter参数kafka-console-consumer.sh --bootstrap-server broker1:9092 \ --topic user_events \ --formatter kafka.tools.DefaultMessageFormatter \ --property print.timestamptrue \ --property print.offsettrue这会输出每条消息的时间戳LogAppendTime和物理 offset当发现消息乱序时可对比 timestamp 判断是 Producer 端时钟漂移还是 Broker 端日志追加异常。实测发现某 IoT 设备时间戳回拨 5 分钟导致消息在时间窗口计算中被丢弃正是通过print.timestamp发现的。另外--from-beginning并非总是有效——当 Topic 启用 Log Compaction 时它只会读取每个 key 的最新值此时需用--offset earliest强制读取所有日志段。3.3 Consumer Group 诊断超越 lag 的深度状态解析kafka-consumer-groups.sh --describe输出的 7 列数据每一列都是关键线索GROUPTOPICPARTITIONCURRENT-OFFSETLOG-END-OFFSETLAGOWNER其中CURRENT-OFFSET是 Consumer 最后提交的 offsetLOG-END-OFFSET是该分区最新消息的 offset二者差值即LAG。但真正的诊断价值在OWNER列它显示client-id/instance-idhost:port例如payment-service-1/100110.1.2.3:45678。当LAG持续增长时先看OWNER是否为空——为空表示该分区无活跃 Consumer可能是 Consumer 实例崩溃或网络隔离若OWNER存在但LAG不变说明 Consumer 卡在业务逻辑如数据库死锁需登录对应主机查进程。更隐蔽的问题藏在--state子命令kafka-consumer-groups.sh --bootstrap-server broker1:9092 \ --group payment-service \ --state输出Stable表示正常PreparingRebalance表示正在重平衡可能因新实例加入或旧实例心跳超时CompletingRebalance是重平衡收尾阶段。若长期卡在PreparingRebalance大概率是session.timeout.ms默认 10s设置过小网络抖动导致频繁触发重平衡。此时需检查 Consumer 配置kafka-configs.sh --bootstrap-server broker1:9092 \ --entity-type clients \ --entity-name payment-service \ --describe但注意clients实体类型在 Kafka 2.6 才支持2.4 及以下需直接查 Consumer 应用日志。另一个杀手级技巧是--reset-offsets# 将 group 重置到 1 小时前的 offset需先停止 Consumer kafka-consumer-groups.sh --bootstrap-server broker1:9092 \ --group payment-service \ --reset-offsets \ --to-datetime 2024-04-05T10:00:00.000 \ --execute \ --all-topics这比手动计算 offset 精确得多因为 Kafka 内部用TimestampAndOffset映射避免了客户端时钟误差。但必须强调--execute前务必--dry-run否则误操作会导致数据重复或丢失。3.4 日志文件深度解析当磁盘报错时的终极手段当 Kafka Broker 日志出现LogDirFailure: /var/lib/kafka/data failedkafka-dump-log.sh是唯一能定位物理损坏位置的工具。假设/var/lib/kafka/data/user_clicks-3/00000000000000000000.log文件异常kafka-dump-log.sh --files /var/lib/kafka/data/user_clicks-3/00000000000000000000.log \ --print-offset-log-time \ --deep-iteration--print-offset-log-time输出每条消息的 offset 和 LogAppendTime--deep-iteration强制遍历所有日志段包括已刷盘的.log和索引.index文件。关键观察点是 offset 序列正常应严格递增若出现offset1002, offset1001说明该位置发生写入乱序极可能是磁盘坏道。更进一步用--verify-index-only参数校验索引文件一致性kafka-dump-log.sh --files /var/lib/kafka/data/user_clicks-3/00000000000000000000.index \ --verify-index-only输出Index file is valid表示索引完好若报Invalid index entry at position X则需重建索引kafka-delete-records.sh --bootstrap-server broker1:9092 \ --offset-json-file reset_offsets.json其中reset_offsets.json指定从损坏位置之后的 offset 开始清理。注意kafka-dump-log.sh默认只解析消息头要查看完整 value 需加--print-data-log但这会极大降低解析速度生产环境慎用。我们曾用此方法定位到一块 SSD 的固件 Bug在 128KB 对齐写入时偶发 CRC 校验失败dump-log显示InvalidRecordException最终推动硬件更换。4. 实战全流程从集群初始化到故障恢复的 12 步操作4.1 初始化集群5 分钟完成最小可行环境第一步永远是验证 Broker 连通性# 测试 Bootstrap Server 是否可达不依赖 ZooKeeper kafka-broker-api-versions.sh --bootstrap-server broker1:9092若返回API versions for broker 1列表证明 Kafka 协议栈正常。接着创建基础 Topic# 创建 3 分区、3 副本的 test-topic保留 1 小时 kafka-topics.sh --bootstrap-server broker1:9092 \ --create \ --topic test-topic \ --partitions 3 \ --replication-factor 3 \ --config retention.ms3600000然后注入测试数据# 发送 10 条消息key 为 testvalue 为 msg-0 到 msg-9 for i in {0..9}; do echo msg-$i | kafka-console-producer.sh \ --bootstrap-server broker1:9092 \ --topic test-topic \ --property parse.keytrue \ --property key.separator: \ --property key.serializerorg.apache.kafka.common.serialization.StringSerializer done注意此处key.separator:是关键否则 key 为空。验证消费kafka-console-consumer.sh --bootstrap-server broker1:9092 \ --topic test-topic \ --from-beginning \ --max-messages 10 \ --print-key \ --key-deserializer org.apache.kafka.common.serialization.StringDeserializer \ --value-deserializer org.apache.kafka.common.serialization.StringDeserializer若输出test - msg-0到test - msg-9说明基础链路打通。此时用kafka-topics.sh --describe查看分区分布kafka-topics.sh --bootstrap-server broker1:9092 \ --topic test-topic \ --describe应看到Replica: 1,2,3均匀分布在 3 个 Broker 上。若某 Broker 显示Leader: none说明该节点未加入集群需检查server.properties中broker.id是否唯一、listeners地址是否可路由。4.2 模拟典型故障网络分区下的 Consumer 行为复现为理解session.timeout.ms的作用我们主动制造网络分区# 在 Consumer 主机上临时屏蔽 Broker 流量模拟网络抖动 sudo iptables -A OUTPUT -d 10.1.1.10 -j DROP # 假设 broker1 IP 是 10.1.1.10启动 Consumerkafka-console-consumer.sh --bootstrap-server broker1:9092 \ --topic test-topic \ --group test-group \ --from-beginning \ --property session.timeout.ms6000 \ --property heartbeat.interval.ms20006 秒后Consumer 日志会出现Marking the coordinator 10.1.1.10:9092 dead紧接着触发重平衡。此时在另一台机器执行kafka-consumer-groups.sh --bootstrap-server broker1:9092 \ --group test-group \ --describe会发现OWNER列为空STATE为Dead。恢复网络sudo iptables -D OUTPUT -d 10.1.1.10 -j DROPConsumer 自动重新加入但LAG可能突增——因为网络中断期间 Producer 仍在写入。此时用--reset-offsets回溯kafka-consumer-groups.sh --bootstrap-server broker1:9092 \ --group test-group \ --reset-offsets \ --to-earliest \ --execute \ --topic test-topic这会将 offset 重置到最早位置确保不丢失消息。但注意--to-earliest仅对未 compact 的 Topic 有效compact Topic 需用--to-datetime。4.3 紧急数据清理精准删除指定时间范围消息某次线上事故中上游系统误发了 2024-04-01 全天的测试数据到生产 Topic需紧急清理。kafka-delete-records.sh是唯一安全方案# 构建 delete.json 文件 cat delete.json EOF { version:1, partitions:[ { topic:payment_events, partition:0, offset:123456789 }, { topic:payment_events, partition:1, offset:987654321 } ] } EOFoffset 如何获取用kafka-run-class.sh# 获取 2024-04-01 00:00:00 的 offset kafka-run-class.sh kafka.tools.GetOffsetShell \ --bootstrap-server broker1:9092 \ --topic payment_events \ --time -2 \ # -2 表示最早时间戳 --partitions 0,1--time -2返回最早 offset--time -1返回最新 offset--time 1712345678000毫秒时间戳返回指定时间最近的 offset。将返回值填入delete.json执行kafka-delete-records.sh --bootstrap-server broker1:9092 \ --offset-json-file delete.json输出Records deletion request for partition payment_events-0 with offset 123456789 has been submitted.即成功。验证kafka-run-class.sh kafka.tools.GetOffsetShell \ --bootstrap-server broker1:9092 \ --topic payment_events \ --time -2 \ --partitions 0若返回值大于 123456789说明清理生效。注意此操作不可逆且仅删除日志段不释放磁盘空间需等待 Log Retention 触发物理删除。4.4 权限加固SASL/PLAIN 认证下的命令行适配当集群启用 SASL/PLAIN 认证后所有命令需增加 JAAS 配置# 创建 jaas.conf 文件 cat jaas.conf EOF KafkaClient { org.apache.kafka.common.security.plain.PlainLoginModule required usernameadmin passwordsecure_password; }; EOF然后在每个命令中指定kafka-topics.sh --bootstrap-server broker1:9092 \ --command-config jaas.conf \ --list--command-config指向 JAAS 文件而非server.properties。若使用 SSL 加密还需添加--command-config ssl.properties其中ssl.properties包含security.protocolSASL_SSL sasl.mechanismPLAIN ssl.truststore.location/path/to/kafka.client.truststore.jks ssl.truststore.passwordchangeit实测发现kafka-console-consumer.sh在 SASL 下需额外指定--consumer-propertykafka-console-consumer.sh --bootstrap-server broker1:9092 \ --command-config jaas.conf \ --topic test-topic \ --consumer-property sasl.jaas.configorg.apache.kafka.common.security.plain.PlainLoginModule required username\admin\ password\secure_password\;这是因为 Consumer 需在运行时动态加载 JAAS而--command-config仅用于初始连接。这个细节在官方文档中被严重弱化但我们在线上踩过三次坑才确认。5. 常见问题与独家避坑指南5.1 “UnknownTopicOrPartitionException” 的 5 种根因与速查表现象可能原因验证命令解决方案kafka-console-producer.sh报错Topic 不存在kafka-topics.sh --list创建 Topic 或检查拼写kafka-console-consumer.sh报错Consumer Group 未创建kafka-consumer-groups.sh --list首次消费自动创建或用--group指定新组名kafka-topics.sh --describe报错Broker 未启动或网络不通telnet broker1 9092检查 Broker 进程和防火墙kafka-consumer-groups.sh --describe报错Group Coordinator 不可用kafka-consumer-groups.sh --bootstrap-server broker1:9092 --list检查 Controller Broker 状态所有命令均报错--bootstrap-server地址错误ping broker1使用--bootstrap-server指向存活的 Broker非 ZooKeeper特别提醒当集群有多个 Broker 时--bootstrap-server应填写全部地址逗号分隔而非仅一个。因为客户端首次连接后会从 Metadata 响应中获取完整集群视图单点故障时可自动切换。我们曾因只写一个地址在该 Broker 重启时所有命令阻塞 30 秒后改为broker1:9092,broker2:9092,broker3:9092彻底解决。5.2 时间戳相关陷阱LogAppendTime vs CreateTimeKafka 支持两种时间戳类型LogAppendTimeBroker 接收时间和CreateTimeProducer 发送时间。kafka-run-class.sh kafka.tools.GetOffsetShell默认使用LogAppendTime但业务常需按CreateTime查询。例如# 获取 2024-04-05 10:00:00 的 offset按 CreateTime kafka-run-class.sh kafka.tools.GetOffsetShell \ --bootstrap-server broker1:9092 \ --topic user_events \ --time 1712340000000 \ --partitions 0 \ --timestamp-type CreateTime若不加--timestamp-type默认为LogAppendTime在高负载时二者可能相差数秒导致数据截断错误。另一个陷阱是--from-beginning它实际读取LogStartOffset而LogStartOffset可能因 Log Compaction 被提前因此--from-beginning不等于“从第一条消息开始”。验证方式kafka-run-class.sh kafka.tools.GetOffsetShell \ --bootstrap-server broker1:9092 \ --topic user_events \ --time -2 \ --partitions 0返回值才是真正的起始 offset。5.3 磁盘空间告警时的应急处理三步法当df -h显示/var/lib/kafka使用率超 90%立即执行第一步定位大日志段# 查找最大的 .log 文件 find /var/lib/kafka/data -name *.log -size 500M | xargs ls -lh第二步检查对应 Topic 的 retention 配置kafka-configs.sh --bootstrap-server broker1:9092 \ --entity-type topics \ --entity-name large-topic \ --describe若retention.ms为默认值7 天而业务只需 1 天立即调整kafka-configs.sh --bootstrap-server broker1:9092 \ --entity-type topics \ --entity-name large-topic \ --alter \ --add-config retention.ms86400000第三步强制触发日志清理# 通知 Kafka 立即检查过期日志 kafka-log-dirs.sh --bootstrap-server broker1:9092 \ --describe \ --topic-list large-topic此命令会刷新 LogDirs 状态加速过期段删除。注意retention.ms修改后Kafka 每 5 分钟检查一次log.retention.check.interval.ms默认值手动触发可缩短等待时间。5.4 Windows 环境下的特殊处理Kafka 命令行工具原生为 Linux/macOS 设计Windows 用户需注意kafka-console-producer.sh在 PowerShell 中需改用kafka-console-producer.bat且echo语法不同# PowerShell 写法 msg-1 | .\kafka-console-producer.bat --bootstrap-server broker1:9092 --topic test-topic路径分隔符--files参数中的 Windows 路径需用正斜杠/或双反斜杠\\单反斜杠\会被解释为转义字符中文字符kafka-console-consumer.sh在 Windows CMD 中可能乱码建议使用 Git Bash 或 WSL内存限制Windows 的kafka-run-class.bat默认 JVM 参数为-Xmx1G处理大日志文件时需修改为-Xmx4G。我们曾帮某客户在 Windows Server 上调试发现kafka-dump-log.bat解析 2GB 日志时 OOM最终通过修改kafka-run-class.bat中的KAFKA_HEAP_OPTS-Xmx4G解决。6. 进阶技巧与生产环境最佳实践6.1 自动化巡检脚本30 行代码构建 Kafka 健康检查将日常检查固化为脚本是避免人为遗漏的关键。以下是一个生产环境使用的kafka-health-check.sh#!/bin/bash BROKERSbroker1:9092,broker2:9092,broker3:9092 TOPIChealth-check-topic GROUPhealth-check-group # 1. 检查 Broker 连通性 if ! kafka-broker-api-versions.sh --bootstrap-server $BROKERS /dev/null 21; then echo CRITICAL: Cannot connect to Kafka cluster exit 1 fi # 2. 检查 Topic 存在性 if ! kafka-topics.sh --bootstrap-server $BROKERS --list | grep -q $TOPIC; then echo CRITICAL: Topic $TOPIC not found exit 1 fi # 3. 检查 Consumer Group Lag LAG$(kafka-consumer-groups.sh --bootstrap-server $BROKERS \ --group $GROUP \ --describe 2/dev/null | awk NR1 {sum$6} END {print sum0}) if [ $LAG -gt 1000 ]; then echo WARNING: Consumer lag is $LAG fi # 4. 检查磁盘使用率需提前配置 df 命令 DISK_USAGE$(df /var/lib/kafka | awk NR2 {print $5} | sed s/%//) if [ $DISK_USAGE -gt 85 ]; then echo CRITICAL: Disk usage $DISK_USAGE% exit 1 fi echo OK: Kafka cluster healthy此脚本可集成到 Zabbix 或 Prometheus Alertmanager实现分钟级