如何在微服务架构中快速完成MySQL环境搭建 微服务数据库环境搭建与服务注册配置

3次阅读

mysql容器化部署需配置网络互通、权限开放、时区字符集统一:使用自定义网络、–bind-address=0.0.0.0、create user…’%’、my.cnf设lower_case_table_names=1及default-time-zone=’+08:00’,jdbc url显式指定servertimezone=gmt%2b8和characterencoding=utf8mb4。

如何在微服务架构中快速完成MySQL环境搭建 微服务数据库环境搭建与服务注册配置

MySQL 容器化部署:用 docker 快速起一个可连通的实例

微服务本地开发阶段,不需要搭完整高可用集群,docker run 一条命令就能拉起一个带初始化数据、开放端口、支持远程连接的 MySQL 实例。关键不是“装 MySQL”,而是让它能被其他服务(比如 spring Boot 的 user-service)立刻连上。

  • 必须加 --network host 或自定义桥接网络(推荐 --network mynet),否则默认 bridge 网络下容器间 DNS 不通,spring.datasource.url=jdbc:mysql://mysql:3306/db 里的 mysql 会解析失败
  • 挂载配置文件比用 -e MYSQL_ROOT_PASSWORD 更可控:把自定义 my.cnf 放进 /etc/mysql/conf.d/,启用 lower_case_table_names=1 避免大小写敏感导致 JPA 表名映射异常
  • 首次启动时用 -v ./init.sql:/docker-entrypoint-initdb.d/init.sql 自动执行建库建用户,其中 CREATE USER 'svc'@'%' IDENTIFIED BY 'pwd'; GRANT ALL ON mydb.* TO 'svc'@'%'; 是后续服务连接必需的

spring boot 服务注册到 Nacos 时连不上 MySQL 的典型原因

不是 Nacos 配置错了,而是 application.yml数据库连接参数和实际容器网络不匹配。Nacos 控制台能看到服务上线,但服务日志反复报 Communications link failure,基本锁定在 JDBC URL 解析或权限问题。

  • spring.datasource.url 中的 host 不能写 localhost127.0.0.1——这是容器内部的回环地址,要写宿主机 IP(如 192.168.1.100)或 Docker 网络别名(如 mysql),前提是两者在同一个 --network
  • Nacos 注册的服务元数据(ipport)由 spring.cloud.nacos.discovery.ip 控制,默认会取网卡第一个非 loopback 地址,若宿主机有多个网卡(比如 VirtualBox 虚拟网卡),可能选错,必须显式指定
  • 检查 MySQL 容器日志:docker logs mysql,出现 Host '172.18.0.3' is not allowed to connect to this MySQL server 就说明用户没开 @'%' 权限,或者 bind-address = 127.0.0.1 没改成 0.0.0.0

多服务共用一套 MySQL 时的 schema 隔离策略

本地联调阶段,order-servicepayment-service 不该共用同一张 orders 表,但也不必为每个服务单独部署 MySQL 实例。用 database 级隔离最轻量,且兼容 mybatis / JPA 的默认行为。

  • 初始化 SQL 中为每个服务创建独立 database:CREATE DATABASE order_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;,对应服务的 spring.datasource.url 指向自己的库,如 jdbc:mysql://mysql:3306/order_db
  • 避免跨库 JOIN:JPA 的 @SecondaryTable 或 MyBatis 的 <select></select> 关联查询在分库后失效,需改用服务间 http 调用(Feign)或事件驱动(rocketmq)获取关联数据
  • Flyway 迁移脚本按服务目录组织:src/main/resources/db/migration/order/V1__init.sql,各服务只扫自己前缀的路径,防止 migration 冲突

Nacos + MySQL 组合调试时最容易忽略的时区与字符集

服务能注册、能连库、SQL 也能执行,但存进去的 timestamp 字段总是差 8 小时,或者中文变 ???——这类问题不会报错,却让业务逻辑出错,排查成本极高。

  • MySQL 容器必须加启动参数:-e TZ=Asia/Shanghai 并在 my.cnf 中设 default-time-zone = '+08:00',否则 JDBC 驱动读 TIMESTAMP 时按 UTC 解析,Spring Boot 的 @Createddate 就会错
  • JDBC URL 必须显式声明字符集:jdbc:mysql://mysql:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=GMT%2B8,漏掉 serverTimezone 参数会导致 java.time.LocalDateTime 类型字段插入为 null
  • Docker Compose 启动时,MySQL 和应用服务的 environment 都要配 TZ=Asia/Shanghai,否则 jvm 默认时区是 UTC,new Date() 和数据库时间对不上

本地跑通不代表生产可用,但所有环境差异几乎都集中在网络可见性、权限粒度、时区字符集这三处。少一个 %、多一个 127.0.0.1、漏一个 utf8mb4,就卡半天。

text=ZqhQzanResources