-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Verify Steps
- Tracker 我已经在 Issue Tracker 中找过我要提出的问题
- Branch 我知道 OpenClash 的 Dev 分支切换开关位于插件设置-版本更新中,或者我会手动下载并安装 Dev 分支的 OpenClash
- Latest 我已经使用最新 Dev 版本测试过,问题依旧存在
- Relevant 我知道 OpenClash 与 内核(Core)、控制面板(Dashboard)、在线订阅转换(Subconverter)等项目之间无直接关系,仅相互调用
- Definite 这确实是 OpenClash 出现的问题
- Contributors 我有能力协助 OpenClash 开发并解决此问题
- Meaningless 我提交的是无意义的催促更新或修复请求
OpenClash Version
v0.47.028
Bug on Environment
Official OpenWrt
OpenWrt Version
Openwrt 6.6.73
Bug on Platform
Linux-mipsle-hardfloat
Describe the Bug
当配置文件包含大型 GEOSITE 规则集(如 GEOSITE,category-ads-all、geosite:cn、geosite:geolocation-! cn)时,OpenClash 频繁启动失败,表现为约 5 秒后自动重启,陷入失败的重启循环。
To Reproduce
失败率估计:
- 已启动状态下重启:100% 失败
- 插件关闭状态下手动启动:90% 失败
- 关闭所有其他插件和脚本:80% 失败
- 开启插件状态下重启路由器(自启):60% 失败
- 关闭插件后重启路由器(自启):30% 失败
- 删除 GEOSITE 规则或使用小配置:0% 失败(100% 成功)
OpenClash Log
**故障日志:**
- 插件日志:`错误:内核启动失败,请查看《内核日志》排查失败原因`
- 内核日志:最后一行日志在加载 `geosite:cn`,并多次重试
OpenClash Config
**已排除因素:**
- 路由器 CPU 和内存性能充足,不是硬件性能问题
- 于路由器和openclash插件设置无关,控制变量仅在配置包含大型 geosite 规则集时出现Expected Behavior
功能建议(以下AI辅助,不一定准确)
建议在 OpenClash 中添加以下可配置选项:
方案一:内核启动超时时间(推荐)
- 位置:设置 → 运行模式 → 内核启动超时时间
- 参数名:
core_startup_timeout - 默认值:10 秒(当前硬编码值)
- 建议范围:10-300 秒
- 说明:等待 clash 进程完全启动并加载配置的最大时间
方案二:启动检测重试次数
- 位置:设置 → 运行模式 → 启动检测重试次数
- 参数名:
core_startup_retry - 默认值:10 次(当前 CORE_WAIT <= 10)
- 建议范围:10-600 次
- 说明:检测内核状态的重试次数,每次间隔 1 秒
方案三:procd 重启延迟调整
- 将
procd_set_param respawn 300 5 3中的延迟从 5 秒调整为可配置 - 或者在检测到 geosite 规则时自动延长延迟时间
预期效果
实现此功能后:
- 用户可根据配置文件大小调整超时时间(如设置为 60-300 秒)
- 内核有足够时间完整加载 geosite.dat 等大文件
- 大型 GEOSITE 规则集的启动成功率达到 100%
- 彻底解决无限重启循环问题
参考案例
此问题在 Merlin Clash 中也存在,通过"检查日志重试次数"设置(从 20 调整到 120)完美解决。该设置本质上延长了启动检测的等待时间,允许配置文件完整加载。
相关代码位置
- 文件:
luci-app-openclash/root/etc/init.d/openclash - 关键行:
- 第 693-696 行:
CORE_WAIT循环(10秒超时) - 第 747-757 行:HTTP API 检测(120秒超时)
- 第 794 行:
procd_set_param respawn 300 5 3
- 第 693-696 行:
- 相关函数:
check_core_status(),start_fail(),start_run_core()
Additional Context
问题根源分析
通过分析 /etc/init.d/openclash 源码,发现存在硬编码的启动超时检测机制:
1. 进程启动超时(10秒)
# 第693-696行
while ( [ -z "$(pidof clash)" ] && [ "$CORE_WAIT" -le 10 ] )
do
sleep 1
let CORE_WAIT++
done- 脚本最多等待 10 秒检测 clash 进程启动
- 加载大型 geosite. dat 文件时,内核可能处于繁忙状态,进程不稳定或短暂阻塞
- 10 秒超时对于大配置文件来说严重不足
2. procd 自动重启机制(5秒间隔)
# 第794行
procd_set_param respawn 300 5 3- 参数含义:
respawn <阈值秒数> <重启延迟> <最大重启次数> - 当进程异常退出时,procd 会在 5 秒后自动重启
- 这正是用户体感"约 5 秒就重启"的原因
3. HTTP API 检测超时(120秒,但实际更早失败)
# 第747-757行
while ( [ -n "$(pidof clash)" ] && [ "$CORE_HTTP_CODE" != "200" ] && [ "$TUN_WAIT" -le 120 ] )
do
CORE_HTTP_CODE=$(curl -m 5 -o /dev/null -s -w '%{http_code}' -H 'Content-Type: application/json' -H "Authorization: Bearer ${da_password}" -XGET http://${lan_ip}:${cn_port}/group)
let TUN_WAIT++
sleep 1
done
if [ "$CORE_HTTP_CODE" != "200" ]; then
LOG_OUT "Error: Core Status Abnormal, Please Check The Log Infos!"
start_fail
fi- 理论上有 120 秒超时,但由于前面的 10 秒进程检测失败,往往更早触发
start_fail()
完整失败流程:
- clash 进程启动,开始加载配置文件
- 加载大型 geosite.dat 时内核繁忙,进程可能短暂阻塞或崩溃
CORE_WAIT在 10 秒内检测不到稳定进程,或 HTTP API 未就绪- 触发
start_fail()→ 杀死进程 → 退出 - procd 检测到异常退出,5 秒后自动重启
- 重启后遇到相同问题 → 无限循环
对比:Merlin Clash 的解决方案
Merlin Clash 插件提供了 "检查日志重试次数" 设置:
- 默认值:20 次,触发相同问题。
- 调整为 60-120 次后,一次即能启动,成功率达到 100%。
- 本质上是延长了启动检测的容忍时间,允许内核有足够时间加载大配置
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working