Spring 项目无法连接 MySQL:Nacos 配置误区排查与解决

在开发过程中,我们使用 Nacos 来管理 Spring Boot 项目的配置,其中包括数据库连接配置。然而,在实际操作中,由于一些概念的混淆,我们遇到了一些连接问题。本文将分享我的故障排查过程,帮助大家避免类似的错误。

问题背景

在我的项目中,使用了 Nacos 来管理 Spring Boot 配置。数据库的连接信息(如 MySQL 配置)存储在 Nacos 配置中心的 shared-mysql.yaml 文件中。原本以为是 Nacos 直接连接 MySQL 容器,但事实上,Spring Boot 项目从 Nacos 拉取配置后,最终是通过本机连接开发服务器上的 MySQL。由于在配置时产生了一些混淆,导致项目无法成功连接到 MySQL 数据库。

1. 项目与 Nacos 配置的集成

我们使用 Nacos 来管理数据库连接配置,具体配置如下:

复制代码
spring:
  cloud:
    nacos:
      username: ${NACOS_USERNAME}
      password: ${NACOS_PASSWORD}
      server-addr: ${NACOS_ADDR}
      discovery:
        namespace: ${NACOS_NAMESPACE}
      config:
        file-extension: yaml
        namespace: ${NACOS_NAMESPACE}
        shared-configs:
          - data-id: shared-mysql.yaml
            group: DEFAULT_GROUP
            refresh: false

其中,shared-mysql.yaml 是存储数据库连接信息的配置文件,Spring Boot 项目会从 Nacos 中读取该文件并解析为 MySQL 配置。

shared-mysql.yaml 文件内容如下:

复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://mysql:3306/db
    username: root
    password: xxxx
    hikari:
      max-lifetime: 30000
      maximum-pool-size: 10

这部分配置在容器化的环境中是可以工作的,mysql 是 Docker 容器的主机名,它会被解析为对应容器的 IP 地址。

2. 问题现象

启动 Spring Boot 项目时并没有出现问题,测试请求登录接口报错:

复制代码
2025-05-07 20:20:18.740  INFO 33828 --- [nio-9091-exec-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2025-05-07 20:20:19.747 ERROR 33828 --- [nio-9091-exec-1] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
	at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-j-8.0.32.jar:8.0.32]
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-j-8.0.32.jar:8.0.32]
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:824) ~[mysql-connector-j-8.0.32.jar:8.0.32]
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:444) ~[mysql-connector-j-8.0.32.jar:8.0.32]
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:237) ~[mysql-connector-j-8.0.32.jar:8.0.32]

进一步排查发现,问题的根源是 Spring Boot 项目无法连接到 MySQL 容器。错误信息中提到的 mysql:3306 主机名无法解析为正确的 MySQL 主机地址,导致数据库连接失败。

但是我就纳闷了,我已经配置了容器的网络,mysql跟nacos都处于同一个网络内,所以我觉得连接信息写容器名称应该能够连接上数据库,但是,我发现有一点我混淆了。

3. 排查过程

3.1 确认 Nacos 配置是否正确

首先,我们检查了 Nacos 配置是否正确注册和读取。通过以下配置,项目应该能够从 Nacos 中获取 shared-mysql.yaml 文件内容:

复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://mysql:3306/db
    username: root
    password: xxxx
    hikari:
      max-lifetime: 30000
      maximum-pool-size: 10

在这里,url 地址使用了容器名称 mysql 作为主机名。然而,mysql 是在 Docker 容器内部使用的主机名,外部的 Spring Boot 项目并不能直接解析该主机名。因此,项目无法通过此地址连接到 MySQL。

3.2 理解问题的根本

经过分析,问题并不在于 Nacos 配置本身,而在于数据库连接的主机地址错误。实际上,Spring Boot 项目需要通过宿主机的 IP 地址连接到 MySQL,而不是通过容器名称 mysql。我在url上直接写容器名称是以为直接在Nacos容器连接mysql容器,并且已经配置了他们在同一个网络,但其实项目只是将配置读取再从本机连接服务器的,所以url中的容器名称需要更改为服务器IP公网地址。

3.3 解决方案:修改 MySQL 主机地址

为了解决这个问题,我们修改了 shared-mysql.yaml 配置中的 url 地址,将 mysql:3306 替换为开发服务器的 公网 IP 地址

复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://<服务器公网IP>:3306/db
    username: root
    password: xxxx
    hikari:
      max-lifetime: 30000
      maximum-pool-size: 10

这样,Spring Boot 项目就能够通过宿主机的公网 IP 地址连接到 MySQL,问题得到了解决。

3.4 确认 Nacos 服务地址与权限

此外,我们还需要确认 Nacos 服务地址是否正确配置,以及是否可以正常访问。可以使用以下命令进行验证:

复制代码
curl http://<NACOS_ADDR>:8848/nacos/v1/ns/catalogs

如果无法访问 Nacos,可能是网络问题或 Nacos 地址配置错误。

3.5 检查 MySQL 容器的访问权限

由于 MySQL 容器默认只允许本地连接,我们需要确保它允许外部访问。可以通过以下命令设置 MySQL 允许外部主机连接:

复制代码
docker exec -it mysql mysql -uroot -pxxxx
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

4. 完整解决方案

4.1 修改 Nacos 配置文件

shared-mysql.yaml 配置中的 url 地址从 mysql:3306 改为 公网IP:3306,并将配置发布到 Nacos。

4.2 确保 Nacos 配置服务可用

检查 Nacos 服务是否正常运行,确保 NACOS_ADDR 配置正确,能够从项目中访问到。

4.3 确保 MySQL 容器外部可访问

通过以下命令确认 MySQL 容器允许外部连接:

复制代码
docker exec -it mysql mysql -uroot -pxxxx
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

4.4 项目配置验证

确认项目的 application.yml 配置正确,并确保 Spring Boot 项目能够从 Nacos 获取正确的 MySQL 配置信息。

4.5 网络连接测试

验证 Spring Boot 项目是否能正常连接到 MySQL,尤其是是否能成功解析 MySQL 主机地址。

5. 总结

通过调整 Nacos 配置文件中的 MySQL 主机地址,并确保 MySQL 容器允许外部访问,最终解决了 Spring Boot 项目无法连接 MySQL 的问题。这个问题的根源是对容器网络与 Nacos 配置的理解偏差,导致了数据库连接地址的配置错误。

希望这篇文章能够帮助大家避免类似的配置误区,快速定位并解决类似问题。如果你有其他问题,欢迎留言讨论!

相关推荐
桃林春风一杯酒41 分钟前
Listremove数据时报错:Caused by: java.lang.UnsupportedOperationException
java·开发语言
bxp13211 小时前
springboot国家化多语言实现
java·spring boot·后端
2401_837088501 小时前
Mysql group by 用法
数据库·mysql
纪元A梦1 小时前
贪心算法应用:边着色问题详解
java·算法·贪心算法
工业互联网专业2 小时前
基于springboot+vue的社区药房系统
java·vue.js·spring boot·毕业设计·源码·课程设计·社区药房系统
API小爬虫2 小时前
如何用爬虫获得按关键字搜索淘宝商品
java·爬虫·python
bing_1582 小时前
在Spring Boot 中如何配置MongoDB的副本集 (Replica Set) 或分片集群 (Sharded Cluster)?
spring boot·后端·mongodb
sanx183 小时前
从零搭建体育比分网站完整步骤
java·开发语言
夏季疯3 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.3.29)
java·笔记·学习
杨浦老苏3 小时前
MCPHub:一站式MCP服务器聚合平台
人工智能·docker·ai·群晖·mcp