同一个网站隔一阵再打开,若等待发生在 DNS 缓存过期后的重新查询,可以尝试 sing-box 1.14.0 的 optimistic。它允许先返回窗口内的过期记录,再到后台刷新。第一次没有缓存的查询仍要等待解析器,不能靠这个开关解决。
这次更新改变了哪一段等待?
1.14.0 正式版于 2026 年 8 月 31 日发布,更新项明确包含乐观 DNS 缓存和查询超时选项。这里按 v1.14.0 固定版本的 DNS 文档操作,没有进行客户端安装或性能实测。Windows、macOS、Linux 命令行和图形客户端都要以实际调用的内核为准,应用版本号不能代替核心版本。
普通缓存尚未超过 TTL 时,本来就能复用结果。新功能关注的是 TTL 已经过期的那一刻:如果条目仍在允许窗口内,就先交付旧答案,同时触发刷新。其代价也很直接,业务可能短暂连接旧地址。正在切换服务器的域名,对新地址的需求可能比少等一次查询更迫切。
如果升级后连配置都无法启动,处理入口是旧 DNS 格式迁移。这篇从已有可运行配置开始,不重写解析器格式。
两个 timeout 应该填在哪里?
DNS 文档把两个值放在不同层级。读配置时先看父对象,再看数字:
| 字段位置 | 控制什么 | 默认或注意事项 |
|---|---|---|
dns.optimistic | 是否允许使用过期记录 | 支持布尔值或对象 |
dns.optimistic.timeout | 过期记录最长可继续使用多久 | 开启后默认 3d |
dns.timeout | 每次 DNS 查询的等待上限 | 默认 10s |
dns.rules[].timeout | 匹配规则的查询等待上限 | 覆盖全局查询超时 |
内核内部解析若另设了 domain_resolver.timeout,也能覆盖全局值,不能只改 dns.timeout 就认定所有查询都用了新时限。
三天并不意味着每三天才刷新一次,也不是强制把所有记录的 TTL 改成三天。触发条件仍是查询命中已过期的缓存。把 dns.timeout 写成 3d,则是在改查询等待时间,方向完全不同。
把开关合并到原配置
在自己的配置目录里复制当前文件,副本命名为 config-before-dns.json。以下命令假定终端就在该目录,待改文件叫 config.json;Windows 使用实际的可执行文件路径。官方配置介绍提供了检查命令:
sing-box check -c ./config.json
检查通过后,把以下示例字段合并到 config.json 原有的 dns 对象。它只是补丁片段,保留自己的 servers、rules、final 和其他顶层配置,不要用它覆盖整个文件。
{
"dns": {
"disable_cache": false,
"disable_expire": false,
"optimistic": {
"enabled": true,
"timeout": "3d"
},
"timeout": "10s"
}
}
disable_cache 与 disable_expire 都和乐观缓存冲突。前者关闭缓存,后者关闭缓存过期,与 optimistic 一起开启会报配置错误。示例显式保留十秒,便于第一次修改时只观察缓存行为;它不是测出来的最佳值。
图形客户端若会从订阅重新生成 JSON,应修改能被保留的配置来源。只改一次生成结果,下一次更新可能丢失字段。保存之后查看客户端实际加载的文件内容,而不是仅看编辑器里的未保存文本。
频繁换地址的域名怎样停用旧答案?
DNS Rule Action提供 disable_optimistic_cache。假设原配置已有标签为 existing-dns 的解析器,下例是放进 dns.rules 数组的一条示例规则;把域名及标签换成实际值。
{
"domain": ["api.example.com"],
"action": "route",
"server": "existing-dns",
"disable_optimistic_cache": true,
"timeout": "10s"
}
这条规则停止为匹配查询返回过期记录,仍可使用 TTL 未过期的普通缓存,所以它不等于每次强制向上游取新地址。例外要放在会提前处理该域名的宽泛规则之前,否则可能根本匹配不到。已经有该域名的规则时,直接编辑那条更清楚,不必再堆一个重复项。
这里仍用十秒,突出两个动作彼此独立。确实需要给这个域名更短的等待上限时,再单独改规则里的 timeout;全局值没有跟着变化。超时并不等于创建了备用服务器。
比如同一解析器偶尔响应慢,缩短等待值只能让客户端更早结束这次查询。它不会减少解析器的处理耗时。若问题是域名解析成功后连接旧服务器失败,应该考虑该域名的缓存例外;若日志显示每次都等不到解析响应,则先处理解析器的可达性。两种表现不适合用同一个数字修复。
页面变快能证明缓存生效吗?
不能只凭第二次打开页面更快下结论。浏览器可能复用了连接,也可能自己缓存了解析结果。重新执行检查命令,再让原客户端加载修改后的配置;观察同一域名的 DNS 查询是否真的经过 sing-box,以及过期后的请求是否伴随后台刷新。
该版本日志源码会给乐观缓存的记录加上 optimistic 前缀,例如 A 记录对应 optimistic A。看到它可以确认这次返回走了乐观缓存,但不能据此认定后台刷新成功;还要查看上游查询或后续响应。
保留一组过期前后的查询时间和返回地址作对照,比连续刷新页面更有用。选择你能查看解析记录的测试域名更容易判断:记录原始 TTL,待其过期后再次请求,并观察上游查询。返回地址相同并不能证明没有刷新,因为上游的新答案也可能相同。不要为了制造差异去改正在使用的业务域名。若日志里完全没有该域名的查询,先沿着TUN 与 DNS 接管日志找到解析路径。Android 还要留意私人 DNS 与客户端冲突,别在没有经过内核的请求上评价缓存。
发现业务仍拿到旧地址时,可以先把 optimistic 改成 false 并重新加载;若本次同时改坏了规则,则恢复保存的完整副本。服务端地址刚迁移的业务,应同时检查应用自身的解析缓存和存量连接,关闭一个内核开关不代表它们会立即重建。