v2.5.1 发布背后的故事:从问题反馈到紧急修复
📢 问题初现:一个 Detailed 的 Issue
6 月 22 日晚上 9 点,一位 Windows 10 用户在 GitHub Issues 页面提交了一篇详尽的 Bug 报告。标题为“节点切换时界面冻结约 1 秒,延迟明显高于以前版本”。报告不仅描述了现象,还附上了操作步骤、屏幕录制 GIF 和一段 Mihomo 内核的 Debug 日志。
“从规则模式切换到全局模式,或者在不同代理组之间切换节点时,整个界面会冻结大约 1 秒钟。鼠标点击没反应,节点列表的滚动也卡住。我用 Process Monitor 看了下,发现 svchost 在这个过程中有大量注册表读写操作。”
这条 Issue 迅速被标记为 bug 和 high-priority。虽然团队正在规划 v2.6.0 的新功能开发,但核心维护者 @kevinsawyer 立即在评论中回复:“感谢详细报告,日志非常关键。我们今晚会尝试复现,最迟明天给出初步结论。”
⏱️ 社区响应时间线
6 月 22 日 21:00
用户提交 Issue,附带日志和屏幕录制。维护者标记为高优先级。
6 月 22 日 22:30
另一位 Windows 用户 @netrunner 在 Issue 下评论确认了同样的问题,并补充了系统配置(i5-12400F、16GB RAM、Win 11 22H2)。
6 月 23 日 02:00
核心维护者在本地环境复现问题。通过二分法锁定问题出现在 v2.5.0 引入的“节点状态实时同步”特性中。
6 月 23 日 10:00
初步根因确定:UI 线程与内核通信线程之间出现了不正确的锁竞争,导致主线程被阻塞。
6 月 23 日 16:00
修复补丁提交到 dev 分支,邀请报告者进行早期测试。
6 月 23 日 20:00
两位用户确认问题已解决,UI 切换流畅度恢复。
6 月 24 日 08:00
完成回归测试,发布 v2.5.1 正式版。
🔬 技术排查:锁竞争的发现过程
问题复现后,团队首先排除了网络延迟和节点配置的因素——因为即使在没有网络流量的情况下,仅切换 UI 也会卡顿。通过 Visual Studio 的 Profiler 和 Windows Performance Toolkit,他们捕获到 UI 线程在调用 UpdateProxyList() 时频繁等待一个名为 core_mutex 的互斥锁。
进一步分析代码发现,core_mutex 最初的设计是为了保护内核配置的热更新,但在 v2.5.0 中不慎被扩展到了 UI 数据获取路径。这是一个典型的锁粒度过大导致的性能回退。
🛠️ 解决方案:分离锁与异步化
修复方案并不复杂,但需要细致的线程安全考量。团队决定:
- 引入细粒度锁
ui_data_mutex:专门保护 UI 需要读取的节点状态数据,与内核配置的core_mutex完全分离。 - UI 数据获取恢复异步:将节点延迟、流量统计等 UI 数据的获取改回异步事件驱动模式,内核通过消息队列将数据推送到 UI 线程,而不是让 UI 线程主动去拉取。
- 增加缓存层:对于节点列表这种高频访问的数据,在 UI 侧增加一层轻量级缓存,减少跨线程通信次数。
✅ 测试验证与发布
修复补丁提交后,两位最初报告问题的用户第一时间进行了测试。他们在包含 30+ 个节点的复杂配置下反复切换代理组和节点,确认 UI 已经恢复到流畅状态,没有任何可感知的延迟。团队还在内部自动化测试平台上增加了“UI 线程响应时间”这一指标,确保未来版本不会再次出现类似退化。
经过一夜的回归测试,v2.5.1 于 6 月 24 日上午正式发布。除主要修复外,还包含了几个社区提出的小改进,比如调整了日志输出的时间戳格式、修复了 DNS Fallback 在部分网络下的异常等。
💬 社区反馈与感谢
v2.5.1 发布后,GitHub Issues 和讨论区迅速收到了正面的反馈。原报告者在 Issue 中写道:
“难以置信的响应速度!从报告到修复竟然不到两天。这次经历让我对开源社区的协作能力有了全新的认识。已 Star 并推荐给了朋友。”
其他用户也纷纷表示切换体验回归流畅,部分人提到内存占用似乎还略有下降(得益于异步化减少了不必要的轮询)。
🔮 后续改进:从 v2.5.1 学到的事
这次紧急修复虽然以极快的速度解决了问题,但也暴露出我们在开发流程和测试覆盖上的一些盲区:
- 性能回归测试不足:未来将为每次 PR 增加 UI 线程响应时间的自动化测试,避免类似问题再次漏网。
- 线程模型文档化:正在编写一份关于 Clash Verge Rev 多线程架构的内部文档,帮助新贡献者理解锁的使用规范。
- 更主动的社区 Beta 测试:考虑建立官方 Beta 通道,让有意愿的用户提前测试新版本,及时发现此类体验问题。