从宿主机连接WSL2中服务的网络延迟超高(长达20s)的解决方案
问题出现
博主最近在使用WSL2进行开发的时候,经常需要使用Navicat等软件连接WSL2中的Docker容器中运行的MySQL/PostgreSQL等数据库,但我经常会遇到匪夷所思的问题:我连接到数据库的时候,通常需要等待约20s的时间才能成功连接,我在进行任何数据库操作的时候也会有同样的延迟——这显然是一个异常情况。
诊断过程
失败记录
首先贴出博主的WSL2网络配置:
1 |
|
博主的WSL2版本信息:
1 |
|
我通过网上搜索,找到了诸如修改MySQL配置文件来禁用MySQL的DNS反向解析、禁用WSL2的DNS代理的方法,但这些方法都不起作用。
偶然发现
在随机的尝试中,我发现:我若在宿主机使用127.0.0.1
访问数据库,可以瞬间连接成功,而若使用localhost
访问数据库,就会出现延迟20s的异常情况。
询问AI后,我了解到了问题的原因:我的系统在连接数据库的时候默认将localhost
解析到了IPv6地址::1
,连接超时后才转而请求127.0.0.1
,这导致了我遇到的异常延迟问题。
采用nslookup
命令来验证:
1 |
|
可以看到系统IPv6回环地址会被优先解析,而Docker默认只监听IPv4地址,导致了问题。
经过我的测试,修改hosts
文件并不能帮助我将localhost
优先解析为127.0.0.1
。
结论
问题原因
- Docker默认只监听IPv4回环地址
0.0.0.0
,不会监听IPv6回环地址::1
。 - Windows中
localhost
优先被解析到IPv6回环地址::1
。
推荐方法
在宿主机连接到WSL2里的服务的时候,应使用127.0.0.1
地址而不是localhost
。
例如从宿主机访问WSL2中运行在Docker中的MySQL的时候,应使用127.0.0.1:3306
来访问。(假设Docker容器的3306端口映射到了WSL内部的3306端口)
其他方法
你还可以通过修改相关设置让localhost
优先解析出IPv4地址来让localhost
可以正常使用。具体的操作方法上网搜索即可得知。可参照文章ping localhost时出现::1的原因以及解决办法 - y夏末y - 博客园的方法进行操作。