-
Notifications
You must be signed in to change notification settings - Fork 123
Force Max Mode
force_max 是面向公共订阅转换服务的最大吞吐资源控制模式。它会在服务开始监听前,根据当前进程实际可用的 CPU、内存、文件描述符和 PID 等资源,计算一组完整、确定且有界的运行预算,并立即启用该预算。
该模式的目标是在已探测到的安全资源边界内尽量提高并发处理能力和吞吐。相应地,它也可能让 CPU、内存、线程、文件描述符、入站连接和出站连接更接近可用上限。
Important
公共服务部署建议在完成资源隔离和压测后启用 force_max。个人私有部署通常不建议启用;默认的 compat 模式已经足以处理少量用户和低频转换,也更适合路由器、OpenWrt 设备及与其他服务共享资源的主机。
Warning
force_max 表示「尽量使用已分配资源」,不表示无限队列、无限连接或容量保证。达到有界准入、内存、连接或请求截止时间后,请求仍可能等待、被拒绝或超时。该模式也不能替代反向代理、访问控制、限流、系统连接容量配置和横向扩容。
| 模式 | 主要行为 | 建议用途 |
|---|---|---|
compat |
默认模式。使用同步、有界的兼容路径,并保留显式配置的基础线程和等待队列限制。 | 个人私有部署、OpenWrt、低频使用、资源紧张或优先保持低开销的环境。 |
adaptive |
使用协作式异步转换路径,并根据运行时压力调整计算许可。 | 希望使用异步路径,同时让程序主动降低部分运行压力的部署。 |
force_max |
使用协作式异步转换路径,在启动时应用硬件感知的完整预算;除硬资源危险外,不因空闲、积压或 CPU 繁忙而逐步收缩。 | 经过压测和监控的公共服务,尤其是专用主机或已明确设置容器资源边界的实例。 |
显式选择 httplib HTTP 后端时,转换仍使用同步兼容路径。若要获得 force_max 的完整协作式异步执行能力,应保留默认的 Beast 后端。
程序在开始监听前完成以下操作:
- 探测当前进程实际可调度的 CPU。探测范围包括进程亲和性、cpuset 和 cgroup CPU 配额。
- 探测内存边界与当前使用量,并检查文件描述符、PID、线程和相关运行时余量。
- 根据当前资源边界计算完整的
ForceMaxBudget。相同资源输入与相同程序版本会得到确定的预算,不需要预热、在线学习或历史校准数据。 - 按预算准备计算、阻塞 I/O、QuickJS、远程抓取、请求所有者和传输准入等运行组件。
- 在所有组件准备和校验通过后一次性启用运行时。任何必要资源无法完整探测、预算无效或运行组件无法准备时,程序都会拒绝启动,不会静默回落到
compat。
启动预算覆盖的主要资源包括:
| 资源 | 预算作用 |
|---|---|
| CPU 与执行线程 | 计算许可、计算工作线程、HTTP 处理线程、I/O 执行线程和 QuickJS 执行通道 |
| 入站请求 | 已接受连接、普通连接、活跃转换、等待请求数量和等待请求字节数 |
| 出站抓取 | 全局活跃连接、单主机连接、可打开连接和空闲连接缓存 |
| 内存 | 请求正文、远程下载、转换工作区、保留响应、缓存、脚本堆栈及各级队列 |
| 文件描述符与 PID | 为入站连接、出站连接、线程和临时运行开销保留余量 |
force_max 会重新计算并应用 max_pending_connections、max_concurrent_threads 和 max_server_threads,因此在该模式下盲目提高这些静态值没有意义。
如果 max_allowed_download_size 为 0,程序仍会从内存账本派生安全下载上限。若显式配置的下载上限无法放入当前预算,服务会拒绝启动。
force_max 不是单纯增加线程数。它会把项目已有的高并发执行能力按当前资源边界组合起来:
- 按请求数量和字节数实施有界准入,避免无限积压耗尽内存。
- 分离计算、阻塞 I/O、脚本和远程抓取,减少慢任务长期占用同一执行通道。
- 使用异步远程抓取、连接复用以及全局和单主机连接上限,提高并发抓取效率并限制单一来源占用。
- 合并内容相同的并发
GET /sub请求,使多个调用方共享一次转换;可选的响应微缓存还能吸收短时间内的重复请求。 - 在请求截止、客户端断开、服务停机或共享转换已无调用方时传播取消,尽快释放不再需要的工作。
- 为健康检查和控制请求保留独立处理余量,避免普通转换完全占满处理能力。
- 保留有限请求截止时间、TLS 验证、有界队列、脚本隔离和安全档位,不通过移除安全边界换取吞吐。
这些机制可以提高资源充足时的并行处理能力,并减少重复请求造成的计算和出站访问。但实际效果仍取决于订阅与规则来源速度、请求内容、目标格式、网络带宽、反向代理、内核连接容量以及宿主机上的其他负载。
force_max 从完整启动预算开始运行,不执行预热、AIMD、在线学习、CPU 利用率降档或逐步开放许可。高 CPU 使用率、CPU 压力停顿指标(PSI)、请求积压和活跃负载本身不会触发自动降档;这是最大吞吐模式的预期行为。
程序仍会持续检查硬资源危险,例如:
- cgroup 内存事件、OOM 事件或内存接近硬边界;
- 运行期间内存、CPU、文件描述符或 PID 上限被缩小;
- 文件描述符或 PID 的安全余量接近耗尽。
出现硬资源危险时,程序会临时收紧计算许可、活跃请求、内存、出站连接等限制,并暂停缓存净增长。危险解除并连续确认后,程序恢复完整启动预算。该保护用于避免硬资源耗尽,不会把 force_max 变成根据日常负载自适应降档的模式。
新部署推荐在 base/pref.toml 中设置:
[advanced]
resource_control = "force_max"环境变量会覆盖配置文件:
services:
subconverter-extended:
environment:
SUBCONVERTER_RESOURCE_CONTROL: force_max修改 Compose 环境变量后重新创建容器:
docker compose up -d --force-recreate subconverter-extended如果实际 Compose 服务名不是 subconverter-extended,请将命令末尾替换为实际服务名。
使用 docker run 时添加:
-e SUBCONVERTER_RESOURCE_CONTROL=force_maxINI:
[advanced]
resource_control=force_maxYAML:
advanced:
resource_control: force_max进入「服务 → SubConverter-Extended → Settings」,将「Resource control override」设为「Hardware-aware maximum」,保存后重启服务。
OpenWrt 通常运行在资源有限且承担路由、DNS、防火墙等任务的设备上。除非设备专门承载公共转换服务,并且已经完成资源隔离和压力测试,否则不建议在 OpenWrt 上启用 force_max。
-
SUBCONVERTER_RESOURCE_CONTROL覆盖配置文件中的advanced.resource_control。 -
force_max_curve_fingerprint和SUBCONVERTER_FORCE_MAX_CURVE_FINGERPRINT已弃用,只保留诊断兼容性。是否填写或匹配均不会改变force_max容量;新部署应保持为空。 -
request_deadline_ms在force_max下仍然生效。不要用无限等待掩盖慢上游或过载。 - 建议保留
enable_request_coalescing=true。只有确认业务需要时才通过SUBCONVERTER_DISABLE_COALESCING关闭请求合并。 -
response_cache_ttl与下载缓存相互独立。公共服务可以根据重复请求比例评估短时响应微缓存,但需要同时考虑内容时效性。 - 保持
allow_insecure_tls=false。关闭 TLS 验证不是性能优化。 - 资源容量相关配置在运行期间冻结。修改模式、CPU 配额、cpuset、内存、PID、文件描述符或相关并发设置后,必须重启进程。
先检查启动日志。成功启用时应同时看到以下关键信息:
RESOURCE_CONTROL_EFFECTIVE mode=force_max effective_mode=force_max ... startup_budget_applied=true ... calculated_budget_valid=true
FORCE_MAX_RUNTIME_PREPARED ...
FORCE_MAX_RUNTIME_READY generation=1
如果出现 FORCE_MAX_RUNTIME_ROLLBACK、资源探测不完整、预算无效或进程退出,不要仅依赖容器自动重启反复尝试。先读取本次启动最早出现的错误,修正资源边界或恢复 compat。
启用 Dashboard 时,/dashboard/data 中的以下字段可用于确认运行状态:
-
resource_control.effective_mode为force_max; -
resource_control.calculated_force_max_budget.valid为true; -
resource_control.calculated_force_max_budget.applied为true; -
runtime_coordinator.ready为true。
最后依次验证:
-
/healthz返回ok; -
/version显示预期版本和源代码修订; - 使用可公开的测试输入完成一次真实
/sub转换; - 在预发布环境执行与真实请求结构相近的并发测试。
只有进程或容器处于运行状态,不能证明 force_max 已正确启用,也不能证明公共服务具备目标容量。
- 明确资源边界。 专用主机可以使用主机资源;共享主机应为容器设置明确的 CPU、内存、PID 和文件描述符边界,并为反向代理、监控和系统服务保留余量。
-
保护公网入口。 按安全与隐私选择
public或strict,并按反向代理与公网部署配置 TLS、访问控制和必要的边缘限流。 -
检查系统连接容量。
force_max不会自动修改 conntrack、listen/SYN backlog、宿主机文件描述符上限或反向代理连接限制。只在监控和压力测试证明存在瓶颈时调整系统参数。 -
进行同条件对比。 使用相同版本、配置、请求集和外部来源,对比
compat与force_max的成功率、吞吐、p50/p95/p99 延迟、CPU、RSS、线程、文件描述符、连接、OOM、重启和 swap。 - 完成持续压测。 短时峰值通过后,再观察长时间运行下的内存、缓存、连接复用、外部来源失败和取消行为。
- 保留回退方案。 记录原配置和容器版本。多实例部署应逐个启用,避免同时改变全部后端。
未完成真实请求压测时,只能确认模式已启用,不能把启动预算或短时测试结果当作 QPS、并发用户数或 SLA 保证。
先检查启动日志中的首个资源探测或预算错误。force_max 要求 CPU、内存、PID 和文件描述符边界可完整观察,并要求完整运行时准备成功。不要通过填写已弃用的硬件指纹尝试绕过检查。
这是最大吞吐模式的可能结果。确认资源占用仍在容器或主机边界内,并检查反向代理、监控和其他服务是否仍有足够余量。如果部署不需要持续承载公共负载,应改回 compat。
瓶颈可能位于远程订阅源、规则源、DNS、网络带宽、反向代理、内核连接表或客户端请求模式。还应确认没有显式选择 httplib 后端。不要仅继续增加线程或放宽队列。
force_max 保留有界准入和有限请求截止时间。先区分是入口代理、应用准入、远程下载、转换执行还是客户端断开造成的失败,再决定扩容、调整上游、修改边缘策略或优化请求结构。
将资源控制改回:
[advanced]
resource_control = "compat"如果使用环境变量,将 SUBCONVERTER_RESOURCE_CONTROL 改为 compat 或移除该覆盖,然后重启进程;修改 Compose 环境变量时重新创建容器。回退后再次检查 /healthz、/version 和真实 /sub 转换。
📘 SubConverter-Extended
🚀 开始使用
📦 部署与更新
🧩 参数与配置
🛡️ 安全、诊断与运维
📚 参考