WSL2 + IntelliJ IDEA + Spring Boot 连接 Windows 本地 MySQL 数据库终极排错指南

前言:当 “理所当然” 遭遇 “红字警告”

作为一名 Java 开发者,在 WSL2 (Windows Subsystem for Linux) 环境下使用 IntelliJ IDEA 开发 Spring Boot 项目,连接位于 Windows 主机上的 MySQL 数据库,这听起来是再常规不过的操作了。我熟练地配置好 application.properties,自信地点击了运行按钮,然而,迎面而来的却不是熟悉的 Tomcat 启动日志,而是一片刺眼的红色异常栈。

这便开启了一段曲折但收获颇丰的排错之旅。本文旨在记录从最初的 Connection refused 到最终成功连接的全过程,希望能为遇到同样问题的同学们提供一份清晰的路线图。

故障排除全记录

第一阶段:最初的错误 Connection refused

一切的起点是这个经典的错误。

org.hibernate.exception.JDBCConnectionException: unable to obtain isolated JDBC connection
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
...
Caused by: java.net.ConnectException: Connection refused

Connection refused (连接被拒绝) 是一个明确的网络信号:我的 Spring Boot 应用(在 WSL 中)发出的连接请求,被目标地址和端口主动拒绝了。

初步分析与错误尝试
  1. IP 地址问题:在 WSL 中,localhost127.0.0.1 指向的是 WSL 自身,而不是外部的 Windows 主机。因此,第一步是找到 Windows 主机的 IP。
    我使用了 WSL 中常用的命令来查找主机 IP:

    cat /etc/resolv.conf | grep nameserver | awk '{print $2}'
    # 输出: 10.255.255.254
    

    于是,我满怀信心地将 spring.datasource.url 中的 localhost 换成了 10.255.255.254

    事后复盘:这是一个关键的误区。这个 IP 是 WSL 用于 DNS 解析的地址,虽然它指向主机,但并非用于服务连接的最佳地址。

  2. 新的错误 Connection timed out: 更换 IP 后,错误变成了连接超时。这通常意味着请求石沉大海,大概率是被防火墙拦截了。

第二阶段:网络层大排查 —— bind-address 的陷阱

Connection refusedConnection timed out 反复出现,说明网络连接本身存在严重问题。为了排除 Spring Boot 和 JDBC 驱动的干扰,我请出了网络诊断的“上古神器” telnet

telnet 10.255.255.254 3306
# 结果: Connection refused

telnet 的结果再次指向 Connection refused,说明问题与 Spring Boot 无关,是纯粹的网络层或 MySQL 服务端配置问题。

核心修正:bind-address

经过一番检查,我发现了 MySQL 配置文件 my.ini 中的一个致命错误。

bind-address 是一个决定 MySQL 服务监听哪个 IP 地址的配置项。默认情况下,为了安全,MySQL 只监听 127.0.0.1,也就是只接受来自本机的连接。

错误的配置
我最初将 bind-address = 0.0.0.0 错误地放在了 [mysql] 区块下。[mysql] 是客户端配置,而 [mysqld] 才是服务端配置!

正确的配置 (my.ini)
必须将 bind-address 移到 [mysqld] 区块下,0.0.0.0 代表监听本机所有 IP 地址。

[mysql]
# 客户端配置...

[mysqld]
# 必须放在这里!
bind-address = 0.0.0.0
port = 3306
# 其他服务端配置...

关键操作:修改完 my.ini 后,必须重启 MySQL 服务!可以在 Windows 的 services.msc 中找到并重启。

第三阶段:柳暗花明 —— 找到真正的 IP 地址

即使正确配置了 bind-address,使用 10.255.255.254 进行 telnet 依然失败。这让我意识到,这个 IP 地址可能根本就是错的。

这时,我转向了 Windows 的 ipconfig 命令,真相终于浮出水面。

C:\Users\YourUser> ipconfig

...
以太网适配器 vEthernet (WSL (Hyper-V firewall)):

   连接特定的 DNS 后缀 . . . . . . . :
   IPv4 地址 . . . . . . . . . . . . : 172.18.32.1
...

vEthernet (WSL) 这个虚拟网卡的 IP 地址,才是 WSL 访问 Windows 主机的正确桥梁!

我立刻用这个新地址进行测试:

telnet 172.18.32.1 3306
# 结果:
# Trying 172.18.32.1...
# Connected to 172.18.32.1.

成功了! 屏幕上 Connected 的字样,宣告了网络层面的所有障碍已被清除。

第四阶段:最后的壁垒 —— MySQL 用户授权

网络通了,我立刻修改 application.properties 并重新运行 Spring Boot 项目。错误变了!

message from server: "Host '172.18.44.123' is not allowed to connect to this MySQL server"

(172.18.44.123 是我的 WSL 在该网络中的 IP)

这是一个可喜的错误!它说明连接请求已经成功到达 MySQL,但被 MySQL 的权限系统拦截了。这是我们之前讨论的“第二道门”。

原因是 MySQL 的 root 用户默认只允许从 localhost 登录。我们需要授权它能从任何主机 (%) 登录。

最终解决方案:授权
  1. 在 Windows 的 CMD 中,进入 MySQL 的 bin 目录并登录:

    D:
    cd D:\mysql-8.4.5-winx64\mysql-8.4.5-winx64\bin
    mysql -u root -p
    
  2. mysql> 提示符下,执行以下两条 SQL 语句:

    -- 1. 允许 root 用户从任何主机登录
    UPDATE mysql.user SET host = '%' WHERE user = 'root';
    
    -- 2. 刷新权限,使修改立即生效
    FLUSH PRIVILEGES;
    

执行完毕后,我再次运行 Spring Boot 项目,久违的启动成功日志终于出现在控制台。至此,所有问题全部解决。

总结与反思

这次排错过程就像是剥洋葱,解决一个问题后,更深层的问题才显现出来。回顾整个过程,有几个关键的知识点值得所有在 WSL 环境下开发的同学注意:

  1. IP 地址的识别localhost 在 WSL 中指向自身。访问主机不能想当然地使用 cat /etc/resolv.conf 中的 nameserver 地址,最可靠的方式是在 Windows 中使用 ipconfig 查找 vEthernet (WSL) 适配器的 IP 地址。

  2. MySQL bind-address 配置:这是允许远程连接的第一道大门。务必确保 bind-address = 0.0.0.0 被正确地配置在 my.ini[mysqld] 区块下,并且一定要重启服务

  3. MySQL 用户权限:这是第二道门。网络通了不代表就能登录,还需要确保数据库用户被授权从你的来源 IP (% 代表所有 IP) 登录。

  4. 诊断工具的使用:当应用层报错时,果断使用 telnet 这样的底层工具进行网络连通性测试,可以有效地将问题范围缩小,避免在应用配置的泥潭里打转。

希望这篇详细的记录能够帮助你绕过我踩过的所有坑,顺利地在 WSL2 中连接到你的数据库。编码愉快!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐