简介:Kafka-Manager(CMAK)2.0.0.2 是面向 Kafka 运维人员与后端开发者的集群管理工具包,用于解决多集群监控、主题与消费者组管理、配置在线调整等日常运维难题,适合已具备一定 Kafka 基础、希望降低管理成本的中高级使用者。压缩包共 780 个文件,约 92.38MB,以 604 个 html 页面和 101 个 jar 依赖为主体,辅以 js、css、字体图标等前端静态资源,以及 bat 启动脚本、conf 配置与日志配置等运行文件,解压后即可按目录结构部署。该版本已预编译完成,对多种 JDK 环境兼容友好,省去自行编译环节。目前已有 390 人学习下载。借助其中的可执行脚本与配置模板,读者能快速搭建管理界面,直观查看节点状态、分区与副本分布,定位消费延迟并完成权限控制,从而提升集群运维效率。
1. 集群监控面板翻车之后:我为什么又回头拆了这份 CMAK 2.0.0.2
凌晨两点被电话叫醒,某业务线的消费组延迟飙到几十万条,运维群里三个人同时打开命令行敲kafka-consumer-groups.sh,结果谁也没法一眼看出到底是哪个 topic 的哪个分区在拖后腿。这种场景做过 Kafka 运维的都懂:命令行能查,但查得慢、看得散、说不清。后来我把压箱底的 kafka-manager(CMAK)2.0.0.2 重新翻出来部署了一遍,才发现这个被很多人当成"老古董"的面板,在消费组 lag 可视化、分区分布、broker 指标这几件事上依然够用。这份 zip 包就是 CMAK 的完整发行版,解压即用,适合手上管着几套 Kafka 集群、又不想为监控再搭一整套重型平台的从业者。下面按我实际拆包、部署、调参的顺序讲,坑都标出来。
2. 解压先看目录:CMAK 2.0.0.2 的包结构与运行前提
拿到 zip 别急着unzip完就启动,先搞清楚里面是什么。CMAK 本质是一个基于 Scala/Play 框架的 Web 应用,2.0.0.2 这个版本号对应的是 kafka-manager 改名 CMAK 之后的稳定发行包,打包方式是把编译好的二进制和启动脚本一起塞进压缩包,所以它不需要你在目标机上装 sbt 重新编译,这一点对生产环境很关键——很多内网机器根本没有外网拉依赖的条件。
2.1 包内文件清单与各自作用
解压后典型结构如下,不同构建可能略有出入,但核心几项不会变:
| 路径 | 作用 | 是否需要改 |
|---|---|---|
bin/cmak | 主启动脚本,最终调用java拉起 Play 应用 | 通常不改,除非要调 JVM 参数 |
conf/application.conf | 全局配置,集群连接、认证、端口都在这 | 必改 |
conf/logback.xml | 日志级别与输出路径 | 按需改 |
lib/ | 全部依赖 jar,含 Kafka 客户端、Play、Akka | 不动 |
conf/routes | Play 路由表 | 不动 |
lib/目录是判断包是否完整的依据:如果解压后lib里 jar 数量明显偏少(正常是几十个),大概率是下载中断导致的残缺包,直接重下,别浪费时间排查启动报错。我见过有人拿着残缺包折腾一下午,最后发现是解压工具把长文件名截断了。
2.2 运行前提:JDK 与 Kafka 版本匹配
CMAK 2.0.0.2 跑在 JVM 上,官方构建一般面向 JDK 8 或 JDK 11。这里有个血泪经验:不要用 JDK 17 及以上直接跑,Play 框架老版本对高版本 JDK 的模块系统兼容性差,启动时容易在反射环节抛InaccessibleObjectException。如果机器上只有高版本 JDK,最省事的做法是单独装一个 JDK 11 并用JAVA_HOME指过去,而不是去改一堆--add-opens参数。
Kafka 侧要注意协议版本。CMAK 通过 Kafka 的 Admin API 和消费者组 API 拿数据,连接的集群版本太新(比如 3.x 之后某些 API 行为变化)时,部分指标可能显示不全。常见做法是在添加集群时把 Kafka 版本选成与实际集群接近的档位,CMAK 会据此选择对应的 API 调用路径。这一步选错,表现是集群能连上但消费组页面空白,很容易误判成权限问题。
# 检查 JDK 版本,确认是 8 或 11 java -version # 解压并进入目录 unzip kafka-manager-2.0.0.2.zip -d /opt/ cd /opt/kafka-manager-2.0.0.2 # 确认 lib 目录 jar 数量正常(几十个量级) ls lib | wc -l上面三条命令是上手前的自检:第一条确认 JDK 大版本,第二条解压到固定路径方便后续做 systemd 服务,第三条用 jar 数量快速判断包完整性。-d指定解压目录,建议放在/opt这类不会被误删的位置,别放/tmp,机器一重启配置全丢。
2.3 为什么选 CMAK 而不是自建脚本
有人会问,现在指标采集方案这么多,为什么还用这个面板。我的判断标准很实际:如果团队规模不大、Kafka 集群数量在个位数、又需要非专职运维也能看懂消费组状态,CMAK 的投入产出比很高——一个 jar 包加一份配置文件,半小时能上线。自建脚本或重型平台适合集群规模大、需要长期留存指标做容量规划的团队。选型没有对错,只有场景匹配。这份包的价值就在于它把"能看"这件事的门槛压到了最低。
3. 配置与启动:application.conf 里真正要动的几个参数
配置是这个包落地时最容易翻车的地方。conf/application.conf里参数很多,但真正影响能不能跑起来、跑起来安不安全的就那么几个。下面按"必须改"和"按需改"分开说,避免新手对着几百行配置发懵。
3.1 必改项:端口、ZK 或 Kafka 连接、基础认证
CMAK 早期版本强依赖 ZooKeeper 存元数据,2.0.0.2 这一代已经支持把状态存到本地文件或 ZK,具体看构建。打开配置文件先找这几项:
# 应用监听端口,默认 9000,冲突就换 play.http.secret.key = "换成一串足够长的随机字符串" # 基础认证,生产环境必须开 cmak.zkhosts = "zk1:2181,zk2:2181,zk3:2181" basicAuthentication.enabled = true basicAuthentication.username = "admin" basicAuthentication.password = "改成强密码" basicAuthentication.realm = "CMAK" # 状态存储方式,单机部署用文件即可 cmak.store.type = "file"play.http.secret.key是 Play 框架用来签名 session 的,默认值公开可见,不改等于把会话伪造的口子留着。cmak.zkhosts只在需要 ZK 模式时填,如果构建支持文件存储,单机场景用file更省事,少一个外部依赖。basicAuthentication三项必须一起开,只开enabled不设用户名密码,启动会直接报错。
提示:
secret.key长度建议 32 位以上随机串,用openssl rand -hex 32生成,别手敲。
3.2 按需项:JVM 堆、日志、跨集群超时
启动脚本bin/cmak里通常有JAVA_OPTS相关变量。管十几个集群时,默认堆容易不够,表现是页面加载到一半卡住或 OOM。我一般把-Xms和-Xmx设成一样,避免运行期扩堆抖动:
# 在启动前导出 JVM 参数,或直接改 bin/cmak 里的默认值 export JAVA_OPTS="-Xms1g -Xmx1g -XX:+UseG1GC" export CMAK_CONFIG=/opt/kafka-manager-2.0.0.2/conf/application.conf # 前台启动,先看日志有没有报错 bin/cmak -Dconfig.file=$CMAK_CONFIGCMAK_CONFIG指定配置文件路径,-Dconfig.file是 Play 读取配置的标准方式,两者指向同一个文件即可。第一次启动建议前台跑,日志直接打屏,能第一时间看到端口占用、配置解析失败这类问题。确认没问题后再改成后台或 systemd。
跨集群场景还要关注连接超时。CMAK 连每个集群都要建 Admin 客户端,网络不通时默认超时可能很长,导致页面整体卡顿。常见做法是在添加集群时把 JMX 和连接超时调小,宁可快速失败也不要拖垮整个面板。
3.3 启动验证:从日志到页面三步确认
启动后别只看进程在不在,按三步验证:第一步看日志里有没有Application started字样;第二步curl本地端口确认 HTTP 能通;第三步浏览器登录后添加一个测试集群,看 broker 列表能否拉出来。
# 1. 看启动日志关键行 tail -f logs/application.log | grep -i "started\|error" # 2. 本地探活 curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9000/ # 3. 添加集群后验证 broker 数量 # 在页面 Clusters 页签下确认 Broker 数与实际一致第一步的日志路径取决于logback.xml配置,默认在logs/下。第二步返回 200 说明 Web 层正常,返回 302 多半是认证拦截,属正常。第三步是真正的功能验证——broker 数对不上,说明连接串或版本档位选错了,回到 3.1 检查。
4. 避坑排查:五个让面板"看着能用其实不能用"的坑
这一节是我在不同环境部署时踩过的真实问题,按"现象 → 原因 → 解决"记下来,遇到同类症状直接对号入座,能省不少时间。
4.1 坑一:页面能登录,集群列表一直转圈
现象:登录成功,点进集群详情,broker 和 topic 区域一直 loading,最终超时。
原因:CMAK 到 Kafka broker 的网络不通,或者添加集群时填的 ZK 地址与 Kafka 实际使用的 ZK 不是同一套。很多环境 Kafka 和 ZK 分属不同网段,面板机器只通了 Web 端口没通 broker 端口。
解决:在面板机器上用telnet broker_ip 9092逐个验证 broker 端口连通性;确认添加集群时填的连接信息与实际集群一致。跨网段场景让网络侧放通面板到 broker 的 9092 及 JMX 端口(如启用)。
4.2 坑二:消费组 lag 显示为 0 或空白
现象:topic 有数据在写,消费组页面 lag 全是 0,或者干脆没有消费组记录。
原因:一是添加集群时 Kafka 版本档位选得比实际低太多,CMAK 走了老的消费者组 API,拿不到新协议的 offset 信息;二是消费组用的是新版协调器,而面板连接的账号没有对应 group 的 Describe 权限。
解决:把集群版本档位调到与实际接近;用kafka-consumer-groups.sh --describe在命令行交叉验证,如果命令行能查到而面板查不到,基本就是权限或版本档位问题。
4.3 坑三:启动报配置解析错误,指向 secret key
现象:启动即退出,日志里Configuration error指向play.http.secret.key。
原因:配置文件里该值留空或仍是默认占位符,Play 在非 dev 模式下拒绝启动。
解决:按 3.1 生成随机串填入。注意 HOCON 格式里字符串要带引号,特殊字符要转义,别把#当成注释截断。
4.4 坑四:多集群下内存持续上涨直至 OOM
现象:跑几天后进程被杀,日志有OutOfMemoryError。
原因:默认堆偏小,且每个集群的连接和指标缓存都占内存,集群数量一多就顶不住。
解决:按 3.2 调大-Xmx并固定-Xms;同时减少不必要的 JMX 采集频率。治标是加堆,治本是只接入真正需要看的集群。
4.5 坑五:升级或迁移后历史配置丢失
现象:换机器部署,之前配好的集群列表和认证全没了。
原因:状态存在本地文件或 ZK 里,只拷了程序目录没拷状态数据。
解决:迁移前确认cmak.store.type,文件模式把对应数据目录一起打包,ZK 模式则确认新环境连的是同一个 ZK。这一步没有后悔药,迁移清单里必须列上。
5. 进阶用法:用 API 把面板数据接进自己的告警链路
面板好看,但真正让 CMAK 产生价值的是它暴露的 HTTP 接口。页面上的集群、topic、消费组数据都能通过 API 拿到,这意味着你可以不依赖它的 UI,把 lag 数据定时拉出来喂给自己的告警系统。这一节讲怎么找到接口、怎么调、以及一个我常用的定时采集脚本。
5.1 找到可用的 API 端点
CMAK 的 Web 路由定义在conf/routes里,打开就能看到所有端点。常用的几个:集群列表、单集群 broker、topic 列表、消费组 lag。接口路径带集群名称作为参数,返回 JSON。认证开启后需要在请求头带 Basic Auth。
# 列出所有集群(替换 host、端口和认证信息) curl -s -u admin:yourpassword \ http://127.0.0.1:9000/api/clusters # 拉某个集群的消费组 lag curl -s -u admin:yourpassword \ "http://127.0.0.1:9000/api/clusters/your-cluster/consumers"第一条返回集群名数组,用来做后续遍历。第二条返回消费组及其各 topic 的 lag 明细,字段结构可以直接映射到告警阈值。注意集群名要 URL 编码,名字里带空格或特殊字符时容易 404,这是最常见的调用失败原因。
5.2 定时采集脚本与阈值判断
下面这个脚本我一般放在 cron 里每五分钟跑一次,把 lag 超过阈值的消费组挑出来推给告警通道。逻辑很直白:拉数据、解析、比对、输出。
import json import urllib.request import base64 CMAK = "http://127.0.0.1:9000" AUTH = base64.b64encode(b"admin:yourpassword").decode() CLUSTER = "your-cluster" THRESHOLD = 100000 # lag 告警阈值,按业务调整 def fetch(path): req = urllib.request.Request(CMAK + path) req.add_header("Authorization", "Basic " + AUTH) with urllib.request.urlopen(req, timeout=10) as r: return json.loads(r.read()) data = fetch(f"/api/clusters/{CLUSTER}/consumers") for group in data.get("consumers", []): total = sum(t.get("lag", 0) for t in group.get("topicPartitions", [])) if total > THRESHOLD: print(f"ALERT group={group['group']} lag={total}")THRESHOLD是核心参数,设太低会天天误报,设太高会漏报,建议先观察一周实际 lag 分布再定。timeout=10防止面板卡住时脚本挂死。topicPartitions字段名以实际返回为准,不同版本可能有差异,第一次跑先打印原始 JSON 确认结构,别直接上生产。
5.3 一个我坚持的习惯
从那以后我每次部署这类面板,都会先花十分钟把 API 拉一遍、把返回结构记下来,再决定要不要接告警。UI 是给人看的,API 才是给系统用的,只依赖 UI 的监控迟早会在半夜让你手忙脚乱。这份 CMAK 2.0.0.2 的包不大,但把配置、启动、排查、API 这几步走通,它就能从一个"看看而已"的面板变成告警链路里的一环。希望帮到你。
本文还有配套的精品资源,点击获取