连接排障 · Clash 技术博客

Mihomo 重载后 CPU 不降:SS 入站修复

Mihomo 重载后无流量仍高 CPU?先区分旧流式密码的 SS 入站与普通出站,核对 v1.19.33 修复、完整重启实际内核,再验证空闲占用、重载和真实连接,保留可用配置回退。

  • Mihomo
  • Shadowsocks
  • SS 入站
  • CPU 占用
  • v1.19.33
本文目录

修改入站设置后,连接已经停了,Mihomo 的 CPU 占用却一直不降;再改一次,空闲占用甚至更高。这时要把“配置加载时暂时变忙”与“监听关闭后仍在空转”分开,先确认忙的是哪一个进程,以及刚才到底关闭了什么入口。

没有流量,为什么重载后 CPU 仍降不下来?

官方 #3314 记录的是旧流式密码的 Shadowsocks 入站关闭问题:更改或移除相关 listeners 条目,或更改 ss-config 后,旧监听的接收循环可能没有退出。即使没有流量也会持续消耗 CPU,再次触发同样的关闭路径还可能叠加,而且未必出现错误日志。

这与代理节点慢、普通 SS 出站失败或所有重载卡顿不同。v1.19.33 已包含对应修复,但没有使用这类入站,或高占用只出现在正常流量期间,就不能直接套用本文。

按进程与发生时机区分

观察到的现象应继续查什么
实际 Mihomo 进程在相关 SS 入站被关闭后,空闲 CPU 持续偏高核对入站类型、密码算法、运行内核与关闭时间。
只在加载大配置时短暂升高,加载完成后回落检查配置校验成本;不要当成监听关闭后空转。
客户端界面忙,Mihomo 进程占用正常检查界面、托盘或日志处理。
无相关入站,或只在大流量转发时升高记录对应业务和其他运行原因,本文不能确认根因。

先找入站设置,别把订阅中的 SS 节点算进去

入站是别的程序或设备连接到这份 Mihomo 实例的入口;出站是 Mihomo 用来连接外部服务的代理节点。

先查看客户端最终交给内核的配置,在 listeners 中找 type: shadowsocks,并检查其 cipher;旧式快捷入口则看顶层 ss-config。仅在 proxies 里看到 type: ss,不足以满足本题条件。

本题的流式密码示例包括 aes-128-ctr、aes-256-cfb、rc4-md5、chacha20、chacha20-ietf 和 xchacha20。

v1.19.33 固定源码把这些兼容算法交给内嵌监听实现;none、AEAD 和 2022 密码走另一实现,不在这个关闭缺陷范围内。chacha20-ietf 与 chacha20-ietf-poly1305 不能因为名字相近就混为一类。

当前 Wiki 的常用入站密码表没有把上述旧流式算法列为新配置选项;本文依据固定版本源码说明已有配置的兼容路径,不建议为复现问题而新建旧密码入站。也不要单方面更改 cipher:依赖这条入口的另一端需要匹配。

从现有故障保存这些证据

  • Mihomo 与界面进程分开观察,记录高 CPU 属于哪一个实际实例。
  • 记下客户端版本、运行中的内核版本及其启动方式,不只写“最新版”。
  • 保留相关 listeners 或 ss-config 的修改前后副本,记录原入站类型、cipher 和关闭时间。
  • 核对故障是否紧跟相关入站更改、移除或关闭,而不是任意一次无关的重载。
  • 本机保留原始配置;公开反馈时删掉入站密码、订阅令牌、私钥和服务器信息。

先保存可用配置,停止反复热重载

先独立备份正在使用的完整配置、覆写、外部资源与客户端设置,记录当前内核版本、系统代理和 TUN 状态。如果这条入站还服务其他设备,先安排可以中断连接的时段,保留不依赖它的管理方式。不要边排查边更新订阅、改 DNS 或清空整个数据目录。

已经出现空转时,不要靠反复删除、添加入站来“清理”。旧版缺陷发生在监听关闭后,继续热重载可能再次触发它。临时恢复应使用应用或服务支持的正常停止方法,确认对应旧实例确实结束,再启动事前验证可用的配置;关闭窗口、停用 TUN 或看不到连接,都不能代替进程退出的确认。

不需要为了本文在旧版上重复制造故障,也不需要开放 external-controller 或复制官方复现与重载脚本。配置测试 -t 通过只能证明相应配置检查完成,不能证明运行中的监听关闭循环已经修好。

取得修复后,完整重启实际运行的内核

Mihomo v1.19.33 的正式发布记录列出修复提交 349af19。固定标签的 listener/shadowsocks/tcp.go 在 Close() 开始时先设置 closed,再关闭监听;接收循环遇到关闭错误时才会退出。这是关闭处理修复,不是降低 CPU 上限或修改节点测速。

让修复进入实际运行的实例

  1. 使用原项目支持的稳定更新方式

    独立内核按 MetaCubeX/mihomo 的正式发布选择匹配系统和架构的版本;图形客户端按该项目支持的应用或内核更新流程操作,不随意覆盖服务目录里的二进制。

  2. 确认更新确实包含 349af19

    v1.19.33 是本文已核对的正式修复版本。FlClash v0.9.2 的更新记录明确包含 Mihomo v1.19.33,可作为有出处的例子;其他客户端和内核分支必须另查自己的记录,不能只比较界面版本号。

  3. 正常停止旧实例,再启动已更新的实例

    保留配置和资源副本,按应用或服务要求正常重启,确认旧实例结束、新实例的启动日志显示预期内核。已经留在旧进程里的循环不能靠换一份配置就认定消失;更新文件但旧进程没退出,也不算修复已经运行。

仅用于已确认的独立命令行内核
mihomo -v

mihomo -v 显示的是当前调用到的程序,可能只是 PATH 中另一份同名文件。必须与实际服务或客户端使用的内核相符;托管内核优先读项目提供的版本信息和启动日志,不为了查询版本强行提取内部程序。

空闲占用、后续重载和真实连接都要检查

在同一设备、相同配置和相近后台活动下,对比完整重启前后的 Mihomo 进程占用。先暂时停止经过该实例的测试流量,观察一段空闲时间,再恢复实际业务;启动瞬间或有真实流量时的峰值,不能当成关闭后持续空转。

只有在修复已经运行、且允许短暂停网的环境中,才进行原本需要的入站更改或移除与恢复。如果业务需要多次这样的重载,分别记录每次之后的空闲 CPU,确认没有随相关关闭次数继续抬升;不必为凑次数反复开关旧版或制造高负载。

验收结果

  • 实际运行内核已确认包含 349af19,旧实例已经结束。
  • 停止测试流量后,内核回到与原先正常空闲状态相近的占用,没有持续空转;不套用别人的 CPU 百分比。
  • 后续确需关闭或更改该入站时,没有重新出现同样的持续占用或逐次叠加。
  • 恢复需要的入站后,原来的合法客户端能重新连接,并完成真实 HTTPS 请求;规则、出站和连接记录符合原设计。
  • 系统代理或 TUN 仅按原用途恢复;退出或停用后,设备仍能回到事前记录的网络状态。

本站没有在真实客户端、路由器或服务器上执行本篇复现,也不提供特定性能倍数或零 CPU 承诺。以上是依据官方缺陷、固定源码和修复记录制定的检查步骤;实际网络、其他高占用原因和客户端集成仍需分别验证。

仍异常时恢复可用方案,保留最小反馈

更新后打不开、入站无法连接或配置不兼容时,先保存第一条错误和当前副本,停止继续重载。按项目支持的方式恢复事前已验证的程序版本、匹配配置和外部资源,避免新旧程序共用唯一数据目录;系统代理和 TUN 按原记录恢复到可用状态。

旧版本可能仍有本题缺陷,回退只是应急,不能当成修复。如果需要暂时停用有问题的入站,先确认依赖它的连接和管理入口,正常停止对应实例后再使用已验证的可用配置;不要只在仍空转的旧进程上删除条目并继续热重载。

仍复发时向项目提供系统和架构、实际运行内核、入站类型与 cipher、发生关闭的具体操作、同条件空闲 CPU 趋势,以及完整重启和后续重载的区别。没有这些前提,保留为未知原因,不把所有高 CPU 都归到 #3314。公开材料只留重现所需的最小关系与脱敏错误,不上传完整订阅或密码。

参考资料