sing-box 的问题很少出现在"能不能连上",多数出现在"连上之后":国内站点走了代理、AI 服务忽快忽慢、想在两条线路之间换个出口却发现得改配置重启。这类问题的根不在节点,而在配置结构的两处——rule_set(规则集)怎么组织、出站(outbound)怎么分组。前者决定"哪些流量被归到同一类",后者决定"这一类流量最终从哪条线路出去"。
这是进阶篇。安装、订阅导入、TUN 启动这些基础流程,站内那篇 sing-box 完全配置指南 已经从头走了一遍,本文不重复。这里只处理三件事:按当前版本把 rule_set 讲透(inline、local、remote 三种形态与缓存机制),把出站策略组设计清楚(selector、urltest、链式 detour),再给一套"改分流不用动规则"的组织方式。
还有一个容易忽略的前提:规则和分组只是调度层,最终体验仍然取决于出口线路本身。本文示例中做延迟对照的是 自由猫 这类 IEPL 专线节点,晚高峰波动小,适合当基准线;如果拿一条本身就在抖动的中转线路当参照,urltest 判出的"最优"会一直跳,你也就没法判断配置到底改对了没有。
一、先对齐版本:rule_set 是当前分流的主线写法
sing-box 的迭代节奏很快,2026 年在用的版本已经把一批旧写法标记为弃用、甚至直接移除。照抄两年前教程最常见的后果有两种:启动直接报错,或者更麻烦的——配置能启动,但某几条规则静默失效,你以为生效了,其实一直没匹配上。
下面这张表是本文会反复用到的版本坐标。查配置问题时,先确认自己用的是哪个版本,再决定写法:
| 版本 | 关键变化 | 对你配置的直接影响 |
|---|---|---|
| 1.8.0 | 引入 rule_set 字段,规则集成为独立配置项 | 新配置一律用 rule_set 组织域名/IP 列表,不再把几百条域名写死在规则里 |
| 1.10.0 | 新增 type: inline 规则集;local 规则集文件被修改后自动重载 | 小规模列表可以直接写在配置里;local 型不用重启就能生效 |
| 1.11.0 | 旧的特殊出站(block、dns)弃用,改为规则动作 | 配置里不要再出现把 block/dns 当出站对象的写法,用 action 表达 |
| 1.12.0 | DNS 服务端格式重构 | 旧版 dns.servers 的写法在 1.14 已被移除,升级后必须改 |
| 1.14.0 | 远程规则集的 download_detour 弃用(改用 http_client);隐式默认 HTTP 客户端弃用;出站使用域名时 domain_resolver 变为必需 | 旧字段官方声明 1.16 移除,现在改比到时候被卡住便宜 |
| 1.15.0 | TUN 的 stack 选项弃用 | 新配置里删掉 stack 即可,官方声明 1.17 移除 |
被弃用不等于立刻不能用,但意味着"跨版本搬配置"这件事风险变高:今天能跑的写法,下次升级后可能变成一条启动错误。判断方法是固定的两步——先用配置检查命令跑一遍,再启动看日志,不要靠"能开网页"来确认配置正确。
# 1) 只校验配置语法与字段合法性,不启动代理
sing-box check -c /etc/sing-box/config.json
# 2) 启动并观察规则集加载情况(前台跑,看清日志再放后台)
sing-box run -c /etc/sing-box/config.json
# 3) 把 JSON 按当前版本重排格式(顺手统一缩进,便于 diff)
sing-box format -w -c /etc/sing-box/config.json
如果你希望把这套配置长期跑在服务器上(systemd 托管、开机自启、日志轮转),做法和普通服务一样;本文只说配置本身,进程管理部分不展开。
二、rule_set 的三种形态:inline、local、remote
规则集有三种存在形式,选错形态是很多"规则不生效"问题的起点。它们不是替代关系,而是分工关系,一份配置里经常三种同时出现。
| 形态 | 适合放什么 | 加载方式 | 更新方式 | 典型坑 |
|---|---|---|---|---|
inline | 十几条以内的自用列表(公司域名、家里 NAS 的 IP 段、要强制走代理的几个站点) | 解析配置时直接读取 | 改配置即改规则 | 把大列表塞进 inline,配置体积暴涨、每次改都要重排整个文件 |
local | 几百条到几千条的自维护列表;或想离线、不受远程可用性影响的列表 | 启动时从本地文件读入 | 文件被修改后自动重载(1.10 起) | 文件路径写相对路径导致工作目录一变就读不到;格式标记与文件内容不匹配 |
remote | 社区维护的大列表(广告域名、地区域名、AI 站点清单) | 首次从 URL 下载,开缓存后落盘复用 | 由 interval 一类的周期选项驱动 | 下载失败没有兜底、没开缓存导致每次启动都重新下载 |
inline 的写法最短,适合当"例外清单"。注意它用的是规则集自己的 rules 数组,里面写的是无出站动作的匹配条件:
{
"route": {
"rule_set": [
{
"type": "inline",
"tag": "my-office",
"rules": [
{ "domain_suffix": [".company.example", ".internal.example"] },
{ "ip_cidr": ["203.0.113.0/24"] }
]
}
]
}
}
local 形态多两个字段:path 指向文件,format 说明文件内容格式(source 是文本/JSON 规则,binary 是编译后的二进制规则集)。同一份规则,二进制形态体积和内存占用都更小,解析也更快——社区大列表动辄上万条域名,这一点在软路由和低配小主机上差别明显。
{
"route": {
"rule_set": [
{
"type": "local",
"tag": "geosite-ad",
"format": "binary",
"path": "./rules/geosite-ad.srs"
}
]
}
}
这里有个常被忽略的细节:format 在路径或 URL 以 .json、.srs 结尾时可以省略,程序会按扩展名推断。但一旦你的文件命名不规范(比如下载回来存成了 ad-list.txt),推断失败就会变成启动错误,报的还是"格式不符"这种看不出哪里错的信息。养成显式写 format 的习惯,能省掉一类排查。
三、远程 rule_set:字段、缓存与"鸡生蛋"问题
远程规则集是大多数人真正会用到的形态:规则内容由社区维护,你只维护一个 URL 和更新周期。但它的行为细节决定了启动速度和稳定性,字段也要按版本写对。
{
"experimental": {
"cache_file": {
"enabled": true,
"path": "./cache.db"
}
},
"route": {
"rule_set": [
{
"type": "remote",
"tag": "geosite-cn",
"format": "binary",
"url": "https://cdn.example.org/rules/geosite-cn.srs",
"download_detour": "direct",
"update_interval": "24h"
}
]
}
}
| 字段 | 作用 | 要不要写 | 说明 |
|---|---|---|---|
tag | 规则集的唯一名字,规则里靠它引用 | 必写 | 命名带内容含义(geosite-cn / ai-list),别用 a、b、c;唯一性由你自己保证,重名不会报错但行为不可预期 |
format | 规则文件的格式 | 建议必写 | source 或 binary;命名规范时可省略,但显式写更稳 |
url | 下载地址 | 必写 | 优先选国内可达的镜像或 CDN;原始 GitHub 地址在国内直连常常拿不到 |
download_detour | 指定用哪个出站下载这份规则 | 1.14 起弃用 | 旧字段,1.16 会移除;新配置改用 http_client |
http_client | 指定下载规则集用的 HTTP 客户端 | 1.14 起推荐 | 配合顶层 http_clients 与 route.default_http_client 显式声明;旧的"隐式套用默认出站"也在 1.14 被标记弃用 |
update_interval | 更新周期 | 已弃用 | 旧配置里还能见到,新配置不要再写,更新交给 HTTP 客户端的缓存策略 |
initial_path | 初始内容的本地文件路径 | 可选(1.14 起) | 启动时若本地没有缓存,先读这个文件,不等首次下载完成——专门用来消灭"首次启动卡住" |
缓存是启动体验的分水岭。远程规则集只有在 experimental.cache_file.enabled 打开时才会落盘缓存;不开缓存意味着每次启动都要重新下载一遍全部规则集。规则集越大、数量越多,启动越慢,而且一旦某个 URL 当天不可达,启动就会被拖住甚至失败。开了缓存之后,首次下载完成即落盘,之后启动直接读本地,后台再更新。
"鸡生蛋"问题是远程规则集的经典故障:你希望规则集通过代理下载(因为直连拿不到),于是在 download_detour 里指定了一个代理出站;但代理出站本身要靠规则集完成分流,规则集又还没下载下来。绕开的方式有两个:一是下载规则集只走直连或国内可达镜像,不要依赖代理出站;二是用 initial_path 给一份本地初始内容兜底,让启动不被下载阻塞。
验证规则集是否真的加载成功,别只看网页能不能开:日志里会记录规则集的下载/读取结果,配置检查命令则能拦住字段级错误。养成"改完先 check,再 run 看日志"的顺序,能挡住九成的静默失效。
四、出站策略组:selector 与 urltest 的分工
出站分组的核心只有两种类型,理解它们的分工,策略组的设计就完成了一半。
| 类型 | 行为 | 关键字段 | 什么场景用 |
|---|---|---|---|
selector | 手动选择,由你决定用哪个成员(当前只能通过 Clash API 切换) | outbounds、default、interrupt_exist_connections | 需要"我说了算"的出口:主力线路、指定地区、需要固定 IP 的业务 |
urltest | 自动测速,选当前延迟最低的成员 | outbounds、url、interval、tolerance、idle_timeout | 线路波动大、只想"哪个快用哪个"的日常流量 |
两者可以互相嵌套:selector 的成员里既有具体节点,也可以有 urltest 组。这是最实用的结构——外层用手动选择决定"走哪个地区",内层用自动测速决定"这个地区里走哪条线路"。
{
"outbounds": [
{ "type": "vmess", "tag": "hk-iepl-01", "server": "203.0.113.10", "server_port": 443, "uuid": "00000000-0000-0000-0000-000000000000" },
{ "type": "trojan", "tag": "hk-iepl-02", "server": "203.0.113.11", "server_port": 443, "password": "example" },
{ "type": "vmess", "tag": "jp-relay-01", "server": "198.51.100.20", "server_port": 443, "uuid": "00000000-0000-0000-0000-000000000000" },
{ "type": "vmess", "tag": "us-res-01", "server": "198.51.100.21", "server_port": 443, "uuid": "00000000-0000-0000-0000-000000000000" },
{ "type": "urltest", "tag": "auto-hk", "outbounds": ["hk-iepl-01", "hk-iepl-02"],
"url": "https://www.gstatic.com/generate_204", "interval": "3m", "tolerance": 50, "idle_timeout": "30m" },
{ "type": "selector", "tag": "main", "outbounds": ["auto-hk", "jp-relay-01", "us-res-01"], "default": "auto-hk",
"interrupt_exist_connections": false },
{ "type": "selector", "tag": "bulk", "outbounds": ["jp-relay-01", "auto-hk"], "default": "jp-relay-01" }
]
}
字段里最值得单独说的是 tolerance。urltest 默认 url 是 generate_204 探测地址、interval 默认 3 分钟、tolerance 默认 50 毫秒、idle_timeout 默认 30 分钟。tolerance 的含义是"新成员要比当前成员快出这个差距才切换"——它存在的意义就是反抖动。把 tolerance 设成 0,两条延迟接近的线路会来回切,表现就是"每隔几分钟卡一下";这类抖动常被误判成机场掉线。
interrupt_exist_connections 则是另一个方向的开关:切换成员时,中断已有连接。默认关闭意味着已建立的连接会继续走旧线路直到自然结束——对下载和长连接友好,但如果你的诉求是"立刻全部切走"(例如某条线路被判为不可用),就需要打开它。注意它对下载类任务的影响:当作大文件下载且线路正好被切换时,打开这个开关会让连接被打断。
测速本身也有成本:urltest 是按 interval 周期发起探测的,节点越多、间隔越短,探测流量和功耗越高。移动端和按流量计费的场景,把 interval 放长、只用一个小规模 urltest 组,比"把所有节点塞进一个自动组"更划算。成员池里放大流量线路时,用 瑶瑶领先 这类入门档大流量的线路做 bulk 组的成员更合适——它的定位是花小钱买大额度,正好承担"下载、更新、镜像拉取"这类不要求低延迟、但要吃流量的活儿,和主力低延迟线路分开,互不抢占。
五、出口 IP 的类型:为什么要为它单独留一个组
规则分流的第二层,其实是"出口 IP 类型"的分野。同样是出站,出口 IP 落在机房(IDC)、住宅(ISP)、还是原生 IP,在目标网站眼里是完全不同的身份:机房 IP 是最容易被批量识别的类型,住宅 IP 与原生 IP 更接近真实用户画像,代价是价格更高、带宽通常更小。
| 出口类型 | 特征 | 适合承载的流量 | 不适合 |
|---|---|---|---|
| 机房 IP | 归属明确为数据中心,识别成本低 | 普通浏览、下载、镜像拉取 | 对 IP 类型敏感的服务注册与长期登录 |
| 住宅 / 原生 IP | 归属为运营商,画像更接近真实用户 | 多账号运营、需要稳定身份的业务、部分流媒体 | 大流量下载(成本高) |
落到配置上,做法是给这类流量单独留一个 selector 组,规则里把它们指向该组,而不是混进日常用的自动组:
{
"outbounds": [
{ "type": "selector", "tag": "identity", "outbounds": ["us-res-01", "jp-res-01"], "default": "us-res-01" }
],
"route": {
"rules": [
{ "rule_set": ["multi-account", "streaming-region-locked"], "outbound": "identity" }
]
}
}
这样做有三个好处:日常流量不会因为身份类节点带宽小而变慢;身份类业务的出口固定,不会今天一个 IP、明天换一个;出问题时排查范围也清楚——是"identity 组"的问题,不是全局问题。稳定身份出口这条线上,仙路湾 的定位正好对应:以住宅/原生 IP 与跨境多账号场景为主,适合放进这个独立组,专门接"机房 IP 扛不住"的那部分流量,与大流量的 bulk 组、低延迟的 main 组互不干扰。
六、链式出站:用 detour 把入口和落地串起来
出站的拨号(dial)字段里有一个 detour,含义是"这条出站的上游出站"。写上它之后,这条出站的其他拨号字段会被忽略,整条链路变成"先经上游出去,再到目标服务器"。这就是链式代理在 sing-box 里的原生写法,也是自建中转 + 落地结构的配置层实现。
{
"outbounds": [
{ "type": "socks", "tag": "relay-cn", "server": "203.0.113.30", "server_port": 1080 },
{
"type": "trojan",
"tag": "land-us",
"server": "land.example.org",
"server_port": 443,
"password": "example",
"domain_resolver": "local",
"detour": "relay-cn"
}
]
}
两个必须注意的点:
domain_resolver不能再省。从 1.14 起,出站服务器地址写域名时必须指定域名解析器(出站级domain_resolver或全局route.default_domain_resolver),否则这个域名由谁解析就说不清了。踩过的典型现象是"配置检查通过、启动也正常,但这条出站永远连不上"。- 链式不是越多层越好。每一层都增加一次握手和一段额外延迟,且任何一层抖动都会体现在最终体验里。中转节点只解决"入口不被封",落地节点才决定出口 IP 与线路质量,两层通常是最优结构。
如果你还没搭过中转结构,只关心"国内入口机 + 海外落地机"怎么选与怎么转发,站内这篇 自建中转加速完全指南 里有 realm、gost 两套转发的具体命令和实测对比,配合本文的 detour 写法可以直接落地。
还有一点要提醒:链式只解决"入口不被封",它不会让线路本身变好。每一层都带来一次额外握手和一段额外延迟,所以对长连接类业务(后台会话、长轮询、需要固定出口的服务),与其叠两层中转,不如直接用一条全程专线、且不参与自动切换的固定出口。像 SS-ID 这类以专线为主的机场就是按这个定位选的:节点数量不多,重点放在单条线路晚高峰的稳定性上,把它放进独立 selector 组手动固定,比塞进 urltest 池里反复测速切换更符合它的用法。
七、把订阅接进出站数组:tag 命名与"别手改生成物"
机场订阅给的是节点,而 sing-box 的配置里,出站是一个显式数组。两者之间需要一个转换或拼接的环节,这一步决定了后面所有分组的稳定性。
常见两条路径:一条是用订阅转换工具把订阅渲染成一份 sing-box 配置(或渲染成片段后拼接),另一条是让面板类工具直接导出 sing-box 格式的订阅。无论走哪条,都会遇到同一个问题:生成物每次更新都会覆盖你的手改内容。把 selector 组的成员写进"每次会被覆盖"的那份文件里,是把自己往坑里推。
可行的组织方式是分文件:生成的节点数组放一份文件,你手写的分组与规则放另一份,用一个稳定的拼接脚本或配置合并步骤把两者组装成最终配置。这样订阅更新只影响节点部分,分组和规则不动。
| 要点 | 做法 | 不这么做会怎样 |
|---|---|---|
| tag 唯一且稳定 | 命名带上含义:{地区}-{线路类型}-{序号},如 hk-iepl-01 | 订阅节点顺序一变,selector 引用的 tag 就断,表现为"分组里的节点不见了" |
| 分组只引用 tag | 规则里引用的是分组 tag(如 main、bulk),不是具体节点 | 换节点需要改规则文件,改完还容易漏 |
| 生成物与手写物分离 | 节点数组自动生成,分组/规则手写维护 | 订阅一更新,手改的分组被覆盖,白干 |
| 保留一个直连与一个兜底 | direct 始终存在于 outbounds,route.final 指向兜底组 | 规则写漏时无出口,流量直接卡死而不是回退 |
如果你既有机场订阅又有自建节点,想让它们合进同一份配置、同一套分组,站内这篇 自建节点统一订阅化完全指南 讲了四种统一路线和 Sub-Store 的编排方式,与本文的分组设计是同一套思路的两端。订阅转换工具本身怎么选、各格式之间怎么互转,则属于另一个话题。
八、分流规则的三层写法:先兜底、再例外、按组走
规则是按顺序匹配的,第一条命中即决定去向。所以规则的书写顺序,比规则的数量重要得多。推荐三层结构:
- 内务层:DNS 流量、私有地址、本机回环,先划出去,避免后面的规则误伤;
- 例外层:明确要直连的(国内域名/IP)、明确要拦掉的(广告、跟踪域名)、明确要特殊出口的(需要固定地区或住宅 IP 的站点);
- 兜底层:剩下的全部交给一个自动测速组,由
route.final决定。
{
"route": {
"rules": [
{ "action": "hijack-dns", "protocol": "dns" },
{ "ip_is_private": true, "outbound": "direct" },
{ "rule_set": ["geosite-ad"], "action": "reject" },
{ "rule_set": ["geosite-cn", "geoip-cn"], "outbound": "direct" },
{ "rule_set": ["ai-list"], "outbound": "main" },
{ "rule_set": ["streaming"], "outbound": "bulk" },
{ "domain_suffix": [".example-bank.com"], "outbound": "main" }
],
"final": "main"
}
}
几个结构性要点:
- 规则引用分组,不引用节点。上面
outbound写的是main、bulk这些分组 tag。这样你要换线路时,只改 selector 的选择,规则一个字不用动——这正是"改分流不用改规则"的实现方式。 - 拦截用动作,不用特殊出站。1.11 起旧的特殊出站已被弃用,用规则的
action表达拦截与 DNS 劫持。 - 直连判断要提前。国内域名/IP 的直连规则必须排在通用代理规则之前,反之就会看到"国内站点绕了一圈国外"的经典现象——延迟高、还浪费流量。
- 规则集可以多条并引。把
geosite-cn与geoip-cn放在同一条规则里,语义是"域名或 IP 命中任一即直连",比拆成两条更省事。
关键业务(长连接、需要稳定出口的服务)建议单独指向一个 selector 组,而不是挂在 urltest 上。urltest 会按延迟自动切换,切换瞬间连接被重建;对长连接类业务,这等于周期性掉线。把这类流量交给一个手动固定的组,是整套结构里最省事、收益也最明显的一条约定。
九、DNS 与规则集的配合:分流对了一半靠这里
分流是否准确,很大程度上取决于 DNS 是否解出了"正确的那一个结果"。规则集是按域名与 IP 匹配的,如果 DNS 阶段就把域名解析成了污染结果,后面的 IP 类规则再精确也没有意义。三个实践要点:
- DNS 流量本身要有明确去向。DNS 请求先被劫持到本地 DNS 模块处理,再由规则决定用哪个服务器解析,不要让 DNS 查询以普通 TCP 流量的身份被规则扫一遍。
- 纯 IP 型规则集在 DNS 规则里的行为有版本差异。1.14 起,DNS 规则中不匹配响应的地址字段写法被弃用,只含 IP 项的规则集(例如 GeoIP 类)需要显式匹配响应内容才成立,旧写法会在启动时被拒绝。
- 优先用域名规则集做分流,IP 规则集做补充。域名规则在解析前就能命中,不依赖解析结果;IP 规则只能等解析完成,且遇到 CDN 与共享 IP 段时噪声更大。
DNS 这一层单独展开内容很多——分服务器设计、防污染、缓存与 TTL、FakeIP 与规则集的配合,每一项都能独立成篇。如果你的问题已经具体到"某些域名解析结果不对",站内这篇 软路由 DNS 分流与防污染完全指南 里有 dnsmasq、SmartDNS、mosdns 与 AdGuard Home 的分工方案,思路同样适用于 sing-box 的 DNS 模块。
十、三个常见需求,直接照抄结构
把前面的零件组装起来,日常遇到的其实就是三类需求。下面给的是结构,不是完整配置,你可以照着改。
| 需求 | 出站结构 | 规则结构 | 注意事项 |
|---|---|---|---|
| 只让 AI 与部分海外站点走代理,其余直连 | 一个 selector(含一个 urltest 组) | 内务层 → 直连层(国内域名/IP)→ AI 规则集指向该 selector → final 设为 direct | final 是 direct 时,漏掉的域名会直连而不是走代理;需要靠规则集覆盖你要的站点 |
| 国内直连 + 广告拦截 + 日常自动选路 | urltest 组 + selector 外壳 | 内务层 → 拦截层 → 直连层 → final = 自动组 | 拦截规则要放在直连规则之前,否则部分广告域名会先被判为直连 |
| 多账号 / 地区限定服务需要固定出口 | 独立的 identity selector 组 | 对应规则集指向 identity 组,其余走日常组 | 该组节点固定不参与自动切换,且成员池不要与 bulk 组共用 |
三类结构有一个共同点:日常流量与特殊流量用不同的组,特殊组固定、日常组自动。很多配置乱掉的根因就是"所有流量都用同一个自动组",结果一头是长连接掉线,另一头是大流量挤占低延迟线路。多机场场景下的分组设计(负载均衡、自动切换、故障转移)还有更多细节,站内这篇 多机场订阅管理与策略组高级配置 是按 Clash 语法展开的,分组思路与本文一致,可以对照着看。
十一、六个高频坑与排查路径
下面六个问题覆盖了这套结构里九成以上的故障。共同点是:现象看着像网络问题,实际根因都在配置结构。
| 现象 | 根因 | 修法 |
|---|---|---|
| 启动报字段错误,或规则集"格式不符" | 文件扩展名与内容不匹配,或格式字段缺失导致推断失败 | 显式写 format;用配置检查命令先跑一遍再启动 |
| 规则集明明配了,却没有任何流量按它分流 | tag 拼写不一致 → 规则引用了一个不存在的规则集 | 统一命名规范,规则里引用的 tag 逐个与定义处对齐 |
| 每次启动都明显卡顿,规则集多的时候尤其明显 | 没有开启缓存文件,每次启动重新下载全部规则集 | 打开 experimental.cache_file.enabled,必要时用 initial_path 兜底 |
| 配置检查通过、启动正常,但某条出站永远连不上 | 出站服务器地址是域名,未指定域名解析器 | 补出站级 domain_resolver 或全局默认解析器 |
| 每隔几分钟卡一下,或下载中途断开 | urltest 的 tolerance 过小导致频繁切换;或 interrupt_exist_connections 打开了 | tolerance 调到 50 以上;确认切换中断开关是否真的需要 |
| 手动切换分组时功能不可用 | selector 目前只能通过 Clash API 控制,未开启 API 或未设密码 | 在 experimental.clash_api 里配好监听地址与 secret,用面板或 API 切换 |
排查顺序建议固定下来:先 check 验字段,再看启动日志里规则集的加载结果,然后用 Clash API 确认分组状态与成员可用性,最后才怀疑节点。跳过前三步直接换节点,是最常见的无效动作。
十二、决策框架:四种用户怎么配
| 你的情况 | 出站结构 | 规则集策略 | 不必做的事 |
|---|---|---|---|
| 只有一个机场,日常浏览 | 一个 urltest 组 + 一个 selector 外壳 | remote 规则集 2~3 份(国内直连、广告拦截、兜底代理) | 不必做链式、不必按地区分组 |
| 两个机场,想主备互切 | 两个 urltest 组各管一个机场,外层 selector 手动选主用 | 同上;把"关键业务"单独指向主用组 | 不必把两个机场的节点混进同一个 urltest 池 |
| 多机场,按地区分工 | 每地区一个 urltest 组 + 外层 selector 选地区 + bulk 组单独放大流量线路 | 地区限定类规则指向对应地区组;大流量规则指向 bulk | 不必追求规则集数量,够用即可 |
| 自建 + 机场混合 | 自建节点进独立组,用 detour 表达链式;机场组做兜底 | 关键业务优先自建组,日常走机场自动组 | 不必把所有规则都改成自建,混合的分工比统一更重要 |
十三、八个高频问题
Q1:rule_set 写 inline 还是 remote?看规模与更新频率。十几条自用域名用 inline,改动即生效;上百条以上、由社区维护的用 remote,配好缓存。介于两者之间、又想离线稳定的用 local。
Q2:远程规则集下载失败会怎样?如果开了缓存,通常还能用上一次落盘的内容启动;没开缓存就要看当次下载是否成功。这也是为什么"首次部署"和"长期运行"是两件事——首次要保证 URL 可达,长期要保证有缓存兜底。
Q3:urltest 判出来的"最快"为什么不是体感最好的?它测的是到探测地址的延迟,不是吞吐也不是稳定性。延迟低的线路可能在晚高峰限速更狠。把 tolerance 留出余量、并给关键业务用独立 selector 固定线路,比追求"自动选最快"更实用。
Q4:分组里的节点名变了,规则要不要改?规则引用的是分组 tag,不用改;要改的是分组定义里的成员列表。这也正是"分组做隔离层"的价值——把易变的部分(节点)和稳定部分(规则)分开。
Q5:可以把所有节点塞进一个 urltest 组吗?能跑,但那意味着每次探测都覆盖全量节点,移动端耗电、按流量计费的成本也高,而且切换频率随之上升。按地区或用途拆成 2~3 个小池更稳。
Q6:interrupt_exist_connections 到底该开还是关?默认关闭,保留已有连接。只有当你需要"切换立即全量生效"时才打开,且要接受下载类连接被打断的代价。
Q7:升级 sing-box 后配置直接报错,先改哪里?按本文第一节的版本表对一遍:特殊出站的旧写法、旧的 DNS 服务端格式、远程规则集的 download_detour、出站域名的解析器,这四项是升级后最常见的报错来源。
Q8:这套结构在软路由上也能用吗?能,而且规则集的本地缓存与规则集数量对启动速度的影响在软路由上更明显:内存与存储都更紧,建议本地大列表用二进制格式、远程规则集只保留真正在用的几份,并确保缓存目录可写。
推荐阅读
- 2026年订阅转换与Sub-Store完全指南:机场订阅格式互转、多机场合并与节点管理实战——本文第七节的订阅渲染与合并环节,在那篇里有工具层面的完整做法
- 2026年科学上网客户端故障排查完全指南:节点连不上、订阅更新失败、超时断流,从报错到修复——本文第十一节的六个坑只是配置结构层,客户端层的报错对照看这篇更省时间
- 2026年路由追踪完全指南:用 traceroute 与 mtr 看懂每一跳、AS 号与去程回程,判断机场线路真伪——配置改完之后,用追踪结果反推线路是否真的走了你以为的那条路径