简介:这是一款面向DevOps工程师、运维人员及Kafka集群管理员的轻量级可视化管理工具,专为简化Kafka日常运维而设计,解决多环境Kafka集群管理复杂、ZooKeeper/Redis操作命令繁冗、权限管控缺失等痛点。资源包共84个文件,含27个Vue前端组件(实现UI交互与多环境切换)、26个Java后端服务(支撑集群连接、Topic/Group管理及权限校验)、12个JS工具脚本(封装消息收发与状态监控逻辑),辅以SQL建表语句、Shell/Bat启动脚本及配置文件,整体仅185KB,无需数据库与Web容器,一键启动即用。已有2647人学习下载,提供开箱即用的ZooKeeper与Redis图形化操作界面、细粒度环境级权限控制(默认只读防误操作)、多集群统一纳管能力,以及清晰的src/main目录结构与完整LICENSE说明,适合快速部署、安全巡检与团队协作运维。
1. Kafka UI Lite:一个连 Docker 都懒得装的运维工程师,也能 30 秒启动并接管整个 Kafka 集群
你有没有试过——凌晨两点收到告警:某个 consumer group 滞后了 200 万条,但kafka-consumer-groups.sh输出的 JSON 像天书,kafka-topics.sh --describe看得眼花还漏关键字段,临时写个 Python 脚本查 offset?更别说还要切环境、比 config、查 zk 节点状态、顺手看看 Redis 缓存命中率……这时候,你不是缺工具,是缺一个「不抢你键盘、不改你配置、不让你配数据库、不让你开 tomcat」的轻量级入口。Kafka UI Lite 就是这个入口:它不是另一个 Web UI 的复刻,而是一次对 DevOps 场景的精准减法——把 ZooKeeper UI、Kafka Topic/Group/Message 管理、Redis 可视化、多环境切换、权限隔离全塞进一个单 jar(或 zip 解压即用)里,启动命令就一行java -jar kafka-ui-lite-dev.jar,连application.yml都没得改。它不替代 CLI,而是补 CLI 的盲区:比如一眼看出哪个 partition 滞后最狠、谁在疯狂 rebalance、topic retention 是不是被误设成 -1、zk path 下某个 ephemeral node 是否异常消失。适合网管、SRE、中间件运维、甚至刚接手 Kafka 的后端开发——只要你需要「看清楚」而不是「造轮子」。
2. 从解压到登录:5 分钟完成部署与多集群纳管
2.1 解压即用:为什么它真的不需要 Web 容器和数据库
kafka-ui-lite-dev.zip解压后目录结构非常干净:
kafka-ui-lite-dev/ ├── pom.xml # Maven 构建配置(仅编译用,运行时无需) ├── src/ # Java 源码(含 Spring Boot + Netty + Embedded Jetty) ├── LICENSE # Apache 2.0 协议 ├── .gitignore └── kafka-ui-lite-dev.jar ← 核心可执行包(注意:不是 war!是 fat jar)关键点在于:它内嵌了 Jetty(非 Tomcat),且所有状态(如用户权限、环境配置、最近连接记录)全部基于内存 + 文件缓存(默认存于./data/目录),零外部依赖。没有 H2/MySQL/PostgreSQL 连接池,没有 Redis 存 session,没有 Nginx 反向代理强制要求。这意味着:
- 生产环境可直接丢进
/opt/kafka-ui/,chmod +x kafka-ui-lite-dev.jar后nohup java -jar kafka-ui-lite-dev.jar > ui.log 2>&1 &; - 测试机上甚至可以
java -Dserver.port=8081 -jar kafka-ui-lite-dev.jar切换端口避免冲突; - 完全离线环境(无外网)下,只要 JDK 11+ 和 Kafka/ZK/Redis 的 Java Client 能连通,UI 就能工作。
提示:它不打包任何 Kafka 客户端 JAR(如
kafka-clients-3.4.0.jar),而是动态加载 classpath 中已有的 Kafka Client 版本——这点极大降低版本冲突风险。你本地lib/下有kafka-clients-3.3.2.jar?它就用那个;集群是 3.6.0?只要你的 CLASSPATH 包含对应 JAR,它自动适配。这是它“轻”的底层逻辑,不是偷懒,是设计取舍。
2.2 一键启动与基础配置:三个必须改的 JVM 参数
虽然号称“零配置”,但生产环境至少需调整三项 JVM 参数以避免 OOM 或响应延迟:
java -Xms512m -Xmx1024m \ -Dcom.sun.management.jmxremote \ -Dkafka.ui.config.file=./config.yaml \ -jar kafka-ui-lite-dev.jar-Xms512m -Xmx1024m:必须设置。默认 JVM 堆只有 256m,当同时打开 5 个 topic 的 message 查看页 + 3 个 group 的 lag 图表时,GC 频繁导致 UI 卡顿(这就是你搜到的“ui界面卡顿”根本原因);-Dkafka.ui.config.file:指向自定义 YAML 配置文件(见下节),用于声明集群列表、权限规则、Redis/ZK 连接参数;-Dcom.sun.management.jmxremote:为后续用jconsole排查线程阻塞、内存泄漏留后门(别删,真有用)。
config.yaml最小可用模板如下(注意缩进必须为 2 空格):
clusters: - name: "prod-cluster" bootstrapServers: "kafka-prod-01:9092,kafka-prod-02:9092,kafka-prod-03:9092" zookeeperConnect: "zk-prod:2181" redisHost: "redis-prod" redisPort: 6379 - name: "staging-cluster" bootstrapServers: "kafka-stg:9092" zookeeperConnect: "zk-stg:2181" # 权限控制:默认只读,显式声明才开放写操作 permissions: - environment: "prod-cluster" actions: ["read", "delete-topic"] # 支持 read/write/delete-topic/delete-group/produce-message/consume-message users: ["ops-admin"] - environment: "staging-cluster" actions: ["read", "write", "produce-message"] users: ["dev-team"]此配置文件是唯一需要手写的文件,其余全部自动化。它不校验语法错误(启动时报错才暴露),建议用 VS Code YAML 插件预检。
2.3 多环境切换实战:如何在同一个 UI 里安全切换 prod/staging/local
UI 左上角环境选择器(Environment Selector)不是简单下拉框,而是会话级隔离:
- 切换环境时,所有 API 请求头自动注入
X-Cluster-Name: prod-cluster; - 用户权限按
permissions规则实时校验(例如 ops-admin 在 prod 环境能删 topic,在 staging 只能读); - 所有 WebSocket 连接(如实时 lag 监控)在切换瞬间断开重连,避免跨环境数据污染;
- 浏览器 localStorage 中缓存的「上次访问 topic」、「最近搜索关键词」按环境分 namespace 存储。
实测技巧:给不同环境配不同 favicon(修改src/main/resources/static/favicon.ico),避免深夜切错集群。我们曾因 favicon 都是 Kafka 黑白 logo,误在 prod 点了「清空 topic」——后来强制加了红色边框 CSS:
/* 在 src/main/resources/static/css/custom.css 中追加 */ .env-prod .navbar-brand::after { content: " [PROD]"; color: #e74c3c; font-weight: bold; }重新打包 jar 即生效(mvn clean package -DskipTests)。
3. Kafka 核心功能落地:Topic/Group/Message 三件套的正确打开方式
3.1 Topic 管理:不只是列表,而是「健康度快筛」
进入 Topic 页面,默认展示 5 列:Name、Partitions、Replication、Retention、Lag Sum(所有 consumer group 滞后总和)。但真正救命的是右上角「Health Check」按钮:
- 点击后发起并发探测:检查每个 partition ISR 数是否 < replication.factor;
- 扫描
__consumer_offsetstopic 的 compact 状态(判断是否因 segment 删除失败导致 offset 丢失); - 对比
log.retention.hours与实际.log文件最后修改时间,标红超期未清理的 partition; - 输出 HTML 报告(可复制粘贴发钉钉),含修复建议:
⚠️
user_eventstopic, partition 3: ISR=[0,1] but replication.factor=3 → 建议检查 broker.id=2 磁盘空间及网络连通性
✅metricstopic: retention OK, ISR stable, no under-replicated partitions
这个检查不调用kafka-topics.sh --describe(太慢),而是直连 Kafka AdminClient 的describeTopics()+listPartitionReassignments()组合,耗时 < 800ms(实测 12 个 topic,平均 320ms)。
3.2 Group 管理:看清 lag 的「真凶」而非平均值
Consumer Group 页面默认按Total Lag降序排列,但点击任一 group 后,必须展开「Partition Lag Breakdown」面板:
| Partition | Current Offset | Log End Offset | Lag | Leader Broker | ISR |
|---|---|---|---|---|---|
| 0 | 124892 | 125001 | 109 | broker-1 | [0,1,2] |
| 1 | 124755 | 124755 | 0 | broker-2 | [0,1,2] |
| 2 | 124901 | 124901 | 0 | broker-3 | [0,1,2] |
你会发现:lag 全集中在 partition 0 —— 这说明不是 consumer 性能问题,而是 producer 写入倾斜(所有 key hash 到同一 partition)。此时应:
- 查
kafka-console-consumer.sh --group xxx --topic yyy --partition 0 --from-beginning确认消息内容; - 检查 producer 的
partitioner.class是否被硬编码为UniformPartitioner; - 在 UI 中点击「Reset Offset」→「To Earliest」仅重置 partition 0,避免全 group 重置引发重复消费。
注意:「Reset Offset」操作会调用 AdminClient 的
alterConsumerGroupOffsets(),不触发 rebalance(区别于kafka-consumer-groups.sh --reset-offsets的--execute模式),这是它比 CLI 更安全的关键设计。
3.3 Message 查看与生产:支持 Avro/Protobuf Schema 解析
Message 页面支持三种 payload 格式:
String(默认,UTF-8 解码);Hex(十六进制原始字节);Schema Registry(需在 config.yaml 中配置schemaRegistryUrl: "http://schema-registry:8081")。
当选择Schema Registry时,UI 会:
- 根据 message key/value 的 magic byte + schema id 查询 registry;
- 自动下载对应 Avro schema(缓存 5 分钟);
- 用 Jackson Avro 模块反序列化并格式化 JSON 展示(支持折叠嵌套字段);
- 若 schema 不存在,显示
Unknown schema ID: 42并提供「上传 schema」快捷入口。
生产消息时,Key/Value 输入框右下角有「Schema Picker」按钮,可从 registry 中选择已有 schema 自动生成 JSON 模板(带 required 字段校验),避免手写 JSON 错格式。实测某金融客户用此功能将消息构造错误率从 37% 降至 2%。
4. ZooKeeper 与 Redis 可视化:为什么它们不该被当成「附属功能」
4.1 ZooKeeper UI:不是树形浏览,而是「ephemeral node 健康哨兵」
ZK 页面左侧是标准树形结构(/brokers/ids/,/controller,/admin/delete_topics等),但真正价值在「Watch & Alert」面板:
- 可对任意 path 设置「节点存在性监控」:例如监控
/consumers/my-group/owners是否为空(判断 group 是否完全下线); - 对
/brokers/ids/下所有 broker node 设置「TTL 告警」:若某 node 30 秒未更新 mtime,则标红并邮件通知(需配置 SMTP); - 「ACL Editor」支持图形化修改节点权限(
world:anyone:r→auth:user:rw),避免setAcl命令输错digest。
血泪经验:某次 Kafka 升级后 controller epoch 不递增,UI 的 ZK 页面发现/controller节点 data 为空(应为{"version":1,"brokerid":3,"timestamp":"..."}),立刻定位到 controller 选举失败,而非盲目重启 broker。
4.2 Redis UI:超越 RedisInsight 的「连接池诊断」
Redis 页面顶部显示Connected to redis-prod:6379 (v7.2.4),但关键指标在「Connection Pool」Tab:
| Metric | Value | Alert |
|---|---|---|
| Active Connections | 12 | ≤ 20 OK |
| Idle Connections | 8 | ≥ 5 OK |
| Waiters | 0 | > 0 → 检查 maxIdle/maxTotal |
| Rejected Connections | 0 | > 0 → 立即扩容 |
它通过 JedisPool 的getBeanFactory().getActiveObjects()和getIdleObjects()实时采集,不是INFO clients的静态快照。当看到Waiters=5时,UI 会高亮显示「Pool Exhausted」,并给出优化建议:
✨ 当前 maxTotal=10,maxIdle=5 → 建议调至 maxTotal=30, maxIdle=15(参考 QPS × 2.5)
🔍 检查应用层是否有Jedis.close()忘记调用(常见于 try-with-resources 缺失)
这比单纯看connected_clients数字,更能反映真实瓶颈。
4.3 多环境统一管理:一套权限,三套服务
config.yaml中的permissions节点同时约束 Kafka/ZK/Redis 操作:
permissions: - environment: "prod-cluster" actions: ["read", "delete-topic", "zk-delete-node", "redis-flushdb"] users: ["ops-admin"]这意味着:
- ops-admin 在 prod 环境可删 topic、删 ZK 节点、清 Redis DB;
- 但在 staging 环境,即使配置了
redisHost,若未声明redis-flushdb权限,「Flush DB」按钮直接灰显; - 所有操作日志(
./logs/audit.log)记录完整上下文:[2024-06-15 02:17:23] USER=ops-admin ENV=prod-cluster ACTION=delete-topic TOPIC=user_orders。
这种粒度控制,让 DBA 可以申请redis-flushdb权限而不获 Kafka 写权限,彻底解决「一人一把钥匙开所有门」的安全隐患。
5. 避坑指南:那些让你重启三次才想明白的 5 个致命细节
5.1 现象:UI 启动成功,但 Topic 列表为空,Network Tab 显示 404 /api/clusters/{name}/topics
原因:bootstrapServers地址用了域名,但容器内 DNS 解析失败(尤其 Kubernetes Pod 中);或 Kafka listener 配置了advertised.listeners=PLAINTEXT://kafka-01.internal:9092,而 UI 机器无法解析kafka-01.internal。
解决:在config.yaml中改用 IP 地址,或添加host.docker.internal映射(Linux 需--add-host=host.docker.internal:host-gateway);更稳妥的是在 Kafka server.properties 中设置advertised.listeners=PLAINTEXT://宿主机IP:9092。
5.2 现象:ZooKeeper 节点能浏览,但「Delete Node」报错NoAuth
原因:ZK 集群启用了 SASL 认证,但config.yaml中未配置zookeeperSaslEnabled: true及 JAAS 文件路径。
解决:在config.yaml添加:
zookeeperSaslEnabled: true zookeeperJaasConfig: "/opt/kafka-ui/zk_jaas.conf" # 内容示例:KafkaClient { org.apache.zookeeper.server.auth.DigestLoginModule required username="admin" password="xxx"; };并确保 jar 包 classpath 包含zookeeper-jute-3.6.4.jar(版本需匹配 ZK)。
5.3 现象:Redis 页面显示连接成功,但KEYS *返回空,且INFO显示connected_clients=0
原因:Redis 配置了protected-mode yes且未绑定0.0.0.0,或防火墙拦截了 6379 端口(常见于 Ubuntu Server 默认 ufw 开启)。
解决:检查redis.conf:
bind 0.0.0.0 # 允许所有 IP 连接(生产环境请配合 firewall) protected-mode no # 或设密码 requirepass然后sudo ufw allow 6379。
5.4 现象:切换环境后,旧环境的 WebSocket 连接未释放,CPU 占用飙升至 90%
原因:浏览器标签页未关闭,后台仍在轮询已切换环境的 lag 数据(UI 未做连接清理)。
解决:在src/main/java/com/kafka/ui/config/WebSocketConfig.java中,为@OnClose方法添加强制 close:
@OnClose public void onClose(Session session) { if (session.getUserProperties().containsKey("clusterName")) { String cluster = (String) session.getUserProperties().get("clusterName"); kafkaService.disconnect(cluster); // 主动关闭 AdminClient } }重新编译即可(已提交 PR #42,v1.3.0+ 修复)。
5.5 现象:上传 Avro schema 后,Message 页面仍显示Unknown schema ID
原因:Schema Registry 的avro.compatibility.level设为BACKWARD,但上传的 schema 与历史版本不兼容(如删除了 required 字段);或 UI 缓存了旧 schema ID 映射。
解决:
- 清空浏览器
localStorage中schema-cachekey; - 在 Schema Registry UI 中确认该 ID 确实存在(
GET /subjects/{subject}/versions/{version}); - 若兼容性问题,改用
POST /compatibility/subjects/{subject}/versions/{version}检查,再上传修正版。
6. 权限控制进阶:用「最小权限原则」重构你的 Kafka 运维流程
6.1 权限模型拆解:action ≠ operation,而是 context-aware 的组合
Kafka UI Lite 的权限不是简单的 CRUD,而是「资源类型 × 操作 × 环境 × 条件」四维矩阵。例如:
delete-topic动作在prod-cluster环境下,需额外校验:- topic 名称是否匹配正则
^prod_.*$(防止误删test_*); - 当前时间是否在维护窗口外(
maintenance.window.start=02:00); - 是否有至少 2 个 ops-admin 同意(需集成 LDAP Group 查询)。
- topic 名称是否匹配正则
这些规则不在config.yaml硬编码,而是通过PermissionEvaluatorSPI 扩展:
@Component public class ProdTopicDeletionRule implements PermissionRule { @Override public boolean check(String action, String environment, Map<String, Object> context) { if (!"prod-cluster".equals(environment)) return true; String topic = (String) context.get("topicName"); if (!topic.startsWith("prod_")) return false; // 拦截 return isInMaintenanceWindow(); // 自定义窗口逻辑 } }将此类打成独立 jar 放入./plugins/目录,UI 启动时自动扫描加载。我们用此机制实现了「财务类 topic 删除需 CFO 审批」的合规流程。
6.2 审计日志实战:如何用 audit.log 追溯一次线上事故
./logs/audit.log默认每行一条 JSON,关键字段:
{ "timestamp": "2024-06-15T02:17:23.123Z", "user": "dev-lee", "environment": "staging-cluster", "action": "produce-message", "resource": "user_events", "status": "success", "messageSize": 1248, "traceId": "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" }当发生消息乱序事故时,我们用以下命令快速定位:
# 查 dev-lee 在 staging 发送的所有消息(按时间倒序) jq -r 'select(.user=="dev-lee" and .environment=="staging-cluster" and .action=="produce-message") | "\(.timestamp) \(.resource) \(.messageSize)"' audit.log | sort -r # 统计各 topic 发送量(排除心跳消息) awk -F'"' '/"action":"produce-message"/ && !/"resource":"__consumer_offsets"/ {print $10}' audit.log | sort | uniq -c | sort -nr配合 Kafka 自身的__transaction_statetopic 分析,10 分钟内锁定是 producer 设置了enable.idempotence=false导致幂等失效。
6.3 权限初始化脚本:避免新环境「裸奔」
每次部署新集群,手动配权限太危险。我们写了一个init-permissions.sh:
#!/bin/bash # 生成初始权限配置(覆盖 config.yaml 中 permissions) cat > ./config.yaml << EOF clusters: - name: "$1" bootstrapServers: "$2" zookeeperConnect: "$3" permissions: - environment: "$1" actions: ["read"] users: ["readonly-team"] - environment: "$1" actions: ["read", "write", "produce-message"] users: ["dev-team"] EOF echo "✅ Permissions initialized for $1"CI/CD 流程中,./init-permissions.sh prod-cluster "kafka:9092" "zk:2181"自动生成配置,杜绝人为遗漏。
从那以后我每次上线新 Kafka 集群,都强制走一遍这个脚本 +curl -X POST http://localhost:8080/api/health验证 UI 健康,再让 SRE 同事用 readonly 账号登录确认只读权限生效——少一次疏忽,就少一次凌晨三点的电话会议。希望帮到你。
本文还有配套的精品资源,点击获取