MrWindKafkaClient 是什么
一个原生桌面窗口,基于 PySide6(Qt6)构建,Kafka 能力全部由 confluent-kafka(librdkafka)提供。
它的定位很明确:只读排查 + 轻量写操作 。不碰 ACL、不做配额、不做副本重分配编排------那些是管控平台该干的事。它要做的是把上面那几件高频小事,压缩到「点开就能看、看完就能走」。

一次排查里实际会用到的东西
看 topic:分区、位点、ISR 一屏摊开
左侧选 topic,右侧概览直接给出消息总数、分区数、时间戳极值、Key / Value 大小(采样统计)。下面是分区明细表:每个分区的消息数、起止 offset、Leader、副本与 ISR 状态。
分区数、Leader 分布、ISR 缺了谁------这几个字段平时是排查「消息写不进去」「副本不同步」的第一现场,放在一张表里比逐个 describe 快得多。
读消息:JSON 树形展开,长内容悬停即见
消息浏览支持按分区过滤、从最新 / 从最旧 / 指定时间段三种模式,每页 20~1000 条。

value 是 JSON 时,下方详情区会渲染成一棵可逐层展开的树,key 和 value 分列,配色区分类型,节点支持展开全部 / 折叠全部。
这里有个细节我做得比较较真:字段值太长显示不全时,鼠标悬停就能看到完整内容。JSON 树的值列再宽也有上限,长字符串会被省略号截断;详情面板的纯文本 value 是 QLabel,长文本按控件高度裁掉、又没滚动条。三个入口(JSON 树字段值、详情面板、表格预览列)都挂了悬停提示,超长时还会注明「仅显示前 N 字符,全文可用『复制 value』获取」。
分页也做了处理:选「全部分区」时,各分区先取候选窗口,读回后按 (timestamp, partition, offset) 全局归并再切页。所以同一页里能同时看到多个分区的消息,整体严格按时间有序------而不是像早期实现那样按分区号硬切,跨分区时间序完全丢失。
查消费组:和消息同屏对照

这是我觉得最值得一说的设计。消费组详情和 topic 详情并排同屏,中间是可拖动的分隔条。左边翻消息,右边同时显示这个消费组的状态、成员数、lag 总量、每个分区的 Start / End / Current / Lag 进度,以及成员列表(Member ID、Client ID、Host、分配策略、已分配分区)。
「这条消息为什么没被消费」这个问题,从前要开两个窗口、心里做关联;现在左右一对照,答案基本就在眼前。
lag 口径也写在界面上,不搞玄学:
lag = end_offset - current_offset
几个不那么"通用"的设计选择
多集群物理隔离。 每个集群一份完整的工作区(列表 + 双栏详情),切换集群不重拉已加载的数据,在途请求的响应只回填发起它的那个集群页。早期版本只有一份物理列表,切集群时迟到响应会把上一个集群的数据写进当前列表------串数据。这版把「纪元」机制加进去,集群页一断开就作废在途请求,串数据的问题从根上没了。
长尾体验:点击必有反馈。 刷新按钮点下去立刻转圈并自禁,列表上方提示「正在刷新 Topics...」,失败时红色原因留在提示条上可以直接重试。主题切换先弹「正在切换主题...」,再执行真正的切换(重设全局 QSS 实测约 1.1s),让这段等待是一次有反馈的过渡,而不是一次卡死。
空态也要有品牌。 界面里所有空态统一走一个公共控件,居中圆形图标 + 主提示 + 次级说明,图标是本软件自己的品牌图,深色主题下自动反色。
工程上我认真了的部分
分层是硬约束。 kafka_client/ 是纯 Python,一行 Qt 都不 import;UI 只通过函数调用它。业务逻辑因此可以脱离 GUI 独立单测,换 GUI 框架也不动协议层。
261 项测试,不需要真实 Kafka。 全部是单元 / 契约 / 布局稳定性测试,python tests/run_all.py 一把跑完,连真实集群都不需要。这套测试里包括对自动换行标签的布局稳定性守卫------这类「宽度↔高度」反馈回路不设防的话,窗口缩放时会持续闪烁。
性能上踩过坑,也量化了。 侧栏列表最初用 setItemWidget,268 行会创建 2688 个真实控件,填充耗时数百毫秒;改成 QStyledItemDelegate 绘制后控件数降到约 8 个,绘制量只与可见行相关。消息表格全列禁用 ResizeToContents(它要遍历全部行测量内容定宽,O(行×列),千条消息即卡顿),改为固定 / 交互列宽并支持鼠标拖拽。重型面板不做整体淡入------QGraphicsOpacityEffect 会让 Qt 每帧把整棵子树渲染进离屏缓冲,在部分显卡驱动上表现为窗口持续闪烁。
打包成 exe 只需一个目录。 Nuitka standalone 模式编译,目标机不用装 Python。产物 42MB 的 MrWindKafkaClient.exe + 依赖目录,Qt6 DLL 以独立文件分发(满足 LGPL「用户可替换 Qt 运行库」的义务)。
它的边界,说在前面
不吹不黑,把限制列清楚,你才好判断它合不合你的场景:
- 消息搜索是扫盘。 Kafka 没有服务端全文索引,只能顺序扫描,所以有扫描上限,超限时界面会明确提示「结果可能不完整」。
- ListGroups 不返回完全空闲的消费组。 这是 broker 的行为,不是工具的缺陷。
- Key / Value 大小是采样值。 精确全量统计得遍历整个 topic,成本过高,不提供。
- current offset 的时间戳依赖消息还在。 若该位点消息已被 retention 删除,显示「已过期」。
- 不提供 ACL / 配额 / 副本重分配编排。 定位是排查工具,不是管控平台。
- 商业使用需要授权。 本项目是**源码可用(source-available)**协议,不是 OSI 开源许可证:非商业使用(学习、研究、非营利内部使用、评估测试)免费;商业使用(含生产环境使用、二次开发对外交付、提供 SaaS / 托管服务)须另行获得作者授权并支付费用。
怎么拿走
代码在 Gitee:
https://gitee.com/zhuzi1988/mrwindkafkaclient
最新版本 v0.4.0,有源码、有打包好的 exe、有完整的 CHANGELOG。
从源码跑起来只要三行:
bash
pip install -r requirements.txt
python main.py
然后点顶部「添加集群」,填 bootstrap.servers(支持 PLAINTEXT / SSL / SASL),保存即自动连接。集群连接信息存在 clusters.json(含密码,权限已收紧,且已在 .gitignore 里)。
如果你觉得这东西对你有用,欢迎提 Issue 和 PR。
如果觉得没用,也欢迎说------这比 star 更有价值。