上周我玩网页游戏时,角色每隔三分钟就卡住不动,随后弹出“与服务器连接中断”。游戏内置延迟只有40ms,但网络诊断却提示DNS解析异常。我重启路由器三次,掉线依旧。后来请来一位擅长网络排查的高手,他看了一眼我的电脑设置,直接说出问题:本地DNS和路由器分配的不匹配,游戏的心跳包在域名解析环节就被丢掉了。
网页游戏比客户端游戏更依赖DNS。每次加载场景、请求资源、重新连接服务器,都要先通过域名解析拿到IP地址。我为了追求更快的解析速度,手动把网卡DNS改成了8.8.8.8,备选填了4.2.2.1。而路由器自动从电信获取的是202.96.128.86。高手指着命令行里ipconfig /all的输出说,你手动指定的国内DNS和国外DNS混在一起,系统会优先向8.8.8.8发起查询,但这个公共DNS在境内没有节点,每次请求都要绕道美国西海岸,游戏客户端等不到结果就判定超时。
他用nslookup对游戏官网域名做了测试,通过8.8.8.8解析返回了三个IP,其中两个在国内,一个在美国,耗时分别为32ms、45ms和286ms。我的电脑却正好选中了那个美国IP,因为公共DNS按自己的排序算法把最快返回的地址放在了首位,而这个地址恰好不在游戏服务器的允许访问列表内。游戏客户端向这个IP发送连接请求,服务器响应数据包被防火墙丢弃,TCP重传三次后,连接被强制关闭。掉线间隔稳定在180秒,恰好对应游戏客户端内置的会话超时时间。
高手没有急着改DNS。他打开资源监视器,看到svchost.exe进程每秒发起大约20次DNS查询,其中失败的有15次。这些失败的查询占用了系统的网络缓冲区,游戏的心跳包被排队处理,延迟从正常的15ms飙升到800ms以上。他又检查了事件查看器,发现大量来源为“Microsoft-Windows-DNS-Client”的错误事件,ID是1014,内容说明“无法联系到DNS服务器”。这一切都指向本地DNS配置混乱。
解决方案其实不复杂。高手在网卡属性里把首选DNS改成114.114.114.114,备选改成223.5.5.5。114是纯境内节点,解析游戏域名不会跨境;223.5.5.5是阿里的公共DNS,支持EDNS Client Subnet,能根据我的真实IP返回最近的游戏节点。改完之后,他运行了ipconfig /flushdns清空本地缓存,又用netsh int ip reset重置了IP协议栈,禁用并启用了一次网卡。重启游戏后,掉线问题立刻消失。

但第二天又出现了轻度掉线,频率不高,每次掉线前会卡顿两秒。高手再次检查,发现我的电脑同时启用了IPv6协议,而且IPv6网卡上配置的DNS是fe80::1。可路由器其实关闭了IPv6分配功能,导致所有IPv6查询直接超时。网页游戏客户端有时会优先走IPv6,等待超时后才回落到IPv4,这中间白白耗掉了几秒,在游戏中就表现为突然移动回原来的位置。高手的解决办法是取消IPv6协议前面的勾选,只保留IPv4,因为目前的游戏资源基本都是走IPv4,禁用IPv6对访问没有影响。
最后还发现一个隐藏问题。我以前装过VPN客户端,它留下了一个叫TAP-Windows Adapter V9的虚拟网卡,虽然已经被禁用,但它的DNS配置残留在了系统的适配器优先级列表里。系统解析域名时,偶尔会把这个虚拟网卡当作出口,结果当然是查不到任何记录。高手在设备管理器里彻底卸载了那个虚拟网卡,再执行一次ipconfig /flushdns,系统日志里的错误ID 1014不再出现。
调整之后我连续玩了三个