路由器开 DNS 缓存,重复解析从 24ms 降到 1ms

打开一个网页,浏览器背后往往要做几十次 DNS 查询:主站域名、图片、统计脚本、广告、CDN 节点,每一项都要先问一次域名服务器「这个网址对应哪个 IP」。每一次查询都要走一段网络往返,在跨运营商、跨境或卫星等延迟偏高的链路上,几十次查询叠加起来,页面还没开始下载就先卡了好几秒。系统或浏览器本身会缓存答案,但缓存只留在这一台设备上,家里其他手机、电视、电脑并不能共享。MakeUseOf 撰稿人 Gregory Gibson 在自用网络里实测发现,把 DNS 缓存放到路由器这一层,全屋设备都能共用同一份结果,重复查询的中位数从 24.35 毫秒降到了 0.98 毫秒。

一、在路由器上打开 dnsmasq 缓存(以 OpenWRT 为例)

多数能刷机的路由器(OpenWRT、梅林固件等)都由 dnsmasq 提供 DNS 服务,直接在路由器上开缓存即可让整网受益。

  1. 通过 SSH 登录路由器,先把上游 DNS 固定为单一公共解析器(如 1.1.1.1),并让 dnsmasq 忽略系统自动生成的 resolv 文件,避免「缓存套缓存」干扰效果:

uci add_list dhcp.@dnsmasq[0].server='1.1.1.1'

uci set dhcp.@dnsmasq[0].noresolv='1'

  1. 先设一份「零缓存」基线便于对照:uci set dhcp.@dnsmasq[0].cachesize='0',并打开查询日志:uci set dhcp.@dnsmasq[0].logqueries='1'
  2. 保存并重启使配置生效:uci commit dhcp,再执行 service dnsmasq restart
  3. 正式开启缓存,把容量调到 1000 条:uci set dhcp.@dnsmasq[0].cachesize='1000',再次 uci commit dhcpservice dnsmasq restart

二、别忘了缓存 HTTPS 记录

dnsmasq 默认只缓存 A、AAAA、CNAME、SRV 这几类记录,而现代浏览器会用 HTTPS 记录来协商 HTTP/3 等能力。若只缓存了 IP,Firefox 等浏览器仍会反复向上游询问 HTTPS 记录。补一条规则即可:

uci add_list dhcp.@dnsmasq[0].cache_rr='HTTPS'

保存重启后,一次预热请求就能把页面的 HTTPS、A、AAAA 记录一并缓存。

三、验证效果

可用 nslookup openwrt.org. 192.168.24.254(换成自家路由器 LAN 口 IP)查看,或翻看 dnsmasq 日志里的 query/cached 标记。实测中,MakeUseOf 首页在关闭缓存时产生了 190 次查询、跨 58 个主机名;开启并预热后只剩 45 次、14 个主机名,整页加载时间缩短约 47%(首字节 641ms→385ms,完全加载 7.04s→3.72s)。

注意事项

需提醒的是,DNS 缓存并不能让整张网页变快——TLS 握手、服务器处理、脚本与图片下载仍是瓶颈,缓存只是去掉了「反复问同一个问题」这段等待。缓存本身有时效,记录到期后 dnsmasq 会自动重新向上游查询,属正常行为。另外,浏览器若开启 DoH(DNS over HTTPS)会绕开路由器设置,测试或追求稳定效果时可在浏览器设置里临时关闭。国产路由器若未开放 SSH,也可在管理页寻找「DNS 缓存/缓存大小」相关选项,原理一致。

来源:MakeUseOf