云计算百科
云计算领域专业知识百科平台

Spring Cloud Alibaba 云上实战(三):Docker Compose 一键编排 MySQL 8.4 + Redis 7 + Nacos 2.4.3(含 MySQL 持久化踩坑全记录)

Spring Cloud Alibaba 云上实战(三):Docker Compose 一键编排 MySQL 8.4 + Redis 7 + Nacos 2.4.3(含 MySQL 持久化踩坑全记录)

系列第 3 篇。在 weblog-mw01(华为云 ECS,192.168.0.79)上落地课程第 1 周"基于 Docker Compose 一键编排部署各类核心中间件"和"集成 Nacos 配置中心":一套 compose 起 MySQL + Redis + Nacos,Nacos 数据持久化到 MySQL,并用 curl 完成"发布配置 → 读回配置"闭环验证。

一、为什么这三个放一台

  • Nacos 的配置持久化依赖 MySQL(derby 内嵌库只适合开发试用,重启丢配置的历史教训太多),两者同机用 compose 内网互联,链路最短;
  • Redis 与 MySQL 都是"数据面",CPU 消耗低、磁盘 IO 为主,8C16G 的机器带这三个实例绰绰有余;
  • 生产上要做的只是把 mysql:8.4 换成主从/托管实例、Nacos 换 3 节点集群,编排思路完全一致。

二、compose 文件逐段精讲

name: weblogmw
services:
mysql:
image: mysql:8.4
container_name: weblogmysql
restart: unlessstopped
environment:
MYSQL_ROOT_PASSWORD: Root@2026
TZ: Asia/Shanghai
command: charactersetserver=utf8mb4 collationserver=utf8mb4_unicode_ci
ports:
"3306:3306"
volumes:
mysqldata:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-pRoot@2026"]
interval: 10s
timeout: 5s
retries: 12

redis:
image: redis:7alpine
container_name: weblogredis
restart: unlessstopped
command: redisserver requirepass Weblog@2026 appendonly yes
ports:
"6379:6379"
volumes:
redisdata:/data

nacos:
image: nacos/nacosserver:v2.4.3
container_name: weblognacos
restart: unlessstopped
depends_on:
mysql:
condition: service_healthy # 关键:MySQL 健康后才起 Nacos
environment:
MODE: standalone
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql # compose 服务名即 DNS
MYSQL_SERVICE_PORT: "3306"
MYSQL_SERVICE_USER: root
MYSQL_SERVICE_PASSWORD: Root@2026
MYSQL_SERVICE_DB_NAME: nacos_config
MYSQL_SERVICE_DB_PARAM: "characterEncoding=utf8&connectTimeout=5000&socketTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true"
NACOS_AUTH_ENABLE: "false"
JVM_XMS: 512m
JVM_XMX: 512m
ports:
"8848:8848" # HTTP 控制台/OpenAPI
"9848:9848" # 2.x gRPC 通道(客户端必须能通!)

几个值得展开的设计点:

① depends_on: condition: service_healthy:Nacos 启动就要连 MySQL。如果只写 depends_on: mysql,只能保证"容器启动"不能保证"服务就绪"——MySQL 首次初始化要 20~30 秒,Nacos 抢跑必然连接失败。healthcheck + service_healthy 是 compose 编排有依赖服务时的标准答案。

② 8848 和 9848 必须一起暴露:Nacos 2.x 客户端用 gRPC 长连接(主端口+1000 = 9848)。只开 8848 的经典症状:控制台能访问,客户端注册/拉配置时超时报错。我们后面跨机联调前专门做了端口预检,9848 通了才敢起应用。

③ utf8mb4 要在 command 里显式声明:MySQL 8 默认 utf8mb4,但要保证 collation 一致(utf8mb4_unicode_ci),否则不同建表语句可能混出 0x255 排序规则的坑。

三、Nacos 建表:从镜像里"偷" SQL 的骚操作

Nacos 官方镜像不带自动建库,需要手动执行 mysql-schema.sql(12 张表:config_info、users、roles…)。但去 GitHub 下载 SQL 文件在国内服务器上大概率超时。其实 SQL 就在镜像里,docker create + docker cp 三步拿出来:

# 1. 创建一个"只创建不运行"的容器拿到文件系统
cid=$(docker create nacos/nacos-server:v2.4.3)
# 2. 把建表SQL拷出来
docker cp "$cid":/home/nacos/conf/mysql-schema.sql /tmp/mysql-schema.sql
# 3. 清理临时容器
docker rm "$cid"

# 建库 + 灌 schema
docker exec -i weblog-mysql mysql -uroot -pRoot@2026 <<'SQL'
CREATE DATABASE IF NOT EXISTS nacos_config DEFAULT CHARACTER SET utf8mb4;
CREATE DATABASE IF NOT EXISTS weblog DEFAULT CHARACTER SET utf8mb4;
SQL

docker exec -i weblog-mysql mysql -uroot -pRoot@2026 nacos_config < /tmp/mysql-schema.sql

实测结果:

-rw-r–r– 1 root root 11042 Sep 11 2024 /tmp/mysql-schema.sql # 11KB,12张表
nacos tables: 13 # show tables 输出13行(12表+表头)

这个技巧对所有"镜像里有初始化资源但官方文档让你去网上下"的中间件都适用(XXL-JOB 的 tables_xxl_job.sql、Skywalking 的 OAP 初始化脚本同理)。

四、踩坑实录:Nacos 连不上 MySQL 8.4(重启循环)

Nacos 起来后一直 Restarting (1),看日志:

Caused by: com.mysql.cj.exceptions.UnableToConnectException:
Public Key Retrieval is not allowed
at …CachingSha2PasswordPlugin.nextAuthenticationStep(…)

根因:MySQL 8.x 默认认证插件是 caching_sha2_password,首连时客户端需要向服务端取 RSA 公钥,而 JDBC 默认禁止公钥检索(防中间人)。Nacos 的 JDBC URL 由 MYSQL_SERVICE_DB_PARAM 环境变量拼出来,默认参数里没有 allowPublicKeyRetrieval。

修复:compose 里给 Nacos 加一行:

MYSQL_SERVICE_DB_PARAM: "characterEncoding=utf8&connectTimeout=5000&socketTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true"

docker compose up -d nacos 重建后:

nacos console http: 200
— nacos readiness: OK

同一个坑还出现在:任何 Spring Boot 应用连 MySQL 8、Kafka Connect 的 JDBC Source、Canal……只要看到 Public Key Retrieval is not allowed,闭眼加 allowPublicKeyRetrieval=true&useSSL=false。

五、验证闭环:发布配置 → 落库 → 读回

Nacos 就绪后,不用开控制台,直接用 OpenAPI 完成配置闭环:

# 发布 weblog-demo.yaml 到 DEFAULT_GROUP
curl -s -X POST 'http://localhost:8848/nacos/v1/cs/configs' \\
–data-urlencode 'dataId=weblog-demo.yaml' \\
–data-urlencode 'group=DEFAULT_GROUP' \\
–data-urlencode 'content=weblog:
welcome: "hello-from-nacos-config-center"
env: huawei-cloud-demo'

# → true

# 读回
curl -s 'http://localhost:8848/nacos/v1/cs/configs?dataId=weblog-demo.yaml&group=DEFAULT_GROUP'
# weblog:
# welcome: "hello-from-nacos-config-center"
# env: huawei-cloud-demo

一个细节:发布后立刻 GET 偶尔返回 config data not exist——Nacos 写内存和异步落库之间有毫秒级窗口,去 MySQL 里查 config_info 表确认行已存在、稍后重试 GET 即可读到。这个"读己之写"的小延迟在生产排障时容易造成误判,值得记住。

再看 MySQL 侧的持久化证据:

— DB config_info rows: weblog-demo.yaml / DEFAULT_GROUP / tenant ''

配置真的落在 nacos_config.config_info 表里,容器重建也不丢。

六、最终状态与验收清单

NAME IMAGE STATUS PORTS
weblog-mysql mysql:8.4 Up 3 minutes (healthy) 0.0.0.0:3306->3306/tcp
weblog-nacos nacos/nacos-server:v2.4.3 Up 10 seconds 0.0.0.0:8848->8848/tcp, 0.0.0.0:9848->9848/tcp
weblog-redis redis:7-alpine Up 3 minutes 0.0.0.0:6379->6379/tcp

验收项结果
MySQL 健康 + utf8mb4 + 业务库 weblog
Redis 密码模式 + AOF + PING → PONG
Nacos readiness OK + 配置发布/读回
Nacos 配置持久化到 config_info 表
业务表 t_visit_log 初始化

七、避坑总结

  • Public Key Retrieval is not allowed:MySQL 8 + 老驱动/中间件的标配坑,加 allowPublicKeyRetrieval=true&useSSL=false。
  • 9848 端口:Nacos 2.x gRPC 端口忘了暴露,客户端全超时,控制台却一切正常——最迷惑人的故障形态。
  • healthcheck 里的密码:mysqladmin ping 带密码会告警(Password on the command line),演示环境可接受,生产建议用 –defaults-extra-file 或专门的健康检查账号。
  • docker compose pull 与 up -d 分离执行:先全量拉镜像再起服务,避免服务启动与镜像下载混在一起,失败重试成本更低。
  • 镜像下载约 1.7GB 用时约 15 分钟(5Mbit/s):云上批量部署中间件,把拉镜像的时间预算留够,或先做镜像预热/镜像仓库同步。
  • 写在最后

    持久层与配置中心就位。下一篇在 weblog-mw02 上编排 Kafka 3.9 KRaft(脱离 ZooKeeper)+ Elasticsearch 8.15,包括 KRaft 的 CLUSTER_ID 生成、advertised.listeners 的容器网络陷阱、ES 的 vm.max_map_count 内核参数,以及中文检索验证。

    系列导航:

    • ✅ 一:4台华为云ECS从规划到初始化
    • ✅ 二:Docker 安装配置与镜像加速避坑
    • ✅ 三:Docker Compose 一键编排 MySQL + Redis + Nacos(本篇)
    • ⏭ 四:Kafka KRaft + Elasticsearch 容器化部署
    • ✅ 五:JDK17 + Gradle8 标准化构建环境与多模块工程
    • ⏭ 六:一个 Spring Boot 微服务的跨机全链路联调
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Spring Cloud Alibaba 云上实战(三):Docker Compose 一键编排 MySQL 8.4 + Redis 7 + Nacos 2.4.3(含 MySQL 持久化踩坑全记录)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!