Docker微服务无法连接3306端口MySQL服务器的问题排查与优化建议
微服务无法连接MySQL的问题优化方案
核心问题分析
出现Communication Link错误的主要原因包括:
- MySQL健康检查仅验证本地socket连接,未确认TCP端口是否对外服务
- 微服务未配置数据库连接的用户名和密码
- MySQL默认限制root仅本地访问,未允许容器网络内的连接
- 数据库启动的健康检查等待时长不足
具体优化步骤
1. 修正MySQL健康检查逻辑
原健康检查用localhost仅验证本地socket,改为验证TCP端口的可用性,确保数据库已准备好接受容器网络的连接,同时延长启动等待时间适配MySQL初始化耗时:
修改common-config.yml中的healthcheck部分:
healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "0.0.0.0", "-u", "root", "-proot"] timeout: 10s retries: 10 interval: 10s start_period: 30s
2. 添加MySQL远程访问权限配置
在common-config.yml的microservice-db-config环境变量中添加MYSQL_ROOT_HOST=%,允许root用户从任何主机(包括容器网络)连接:
environment: MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_HOST: "%"
3. 完善微服务的数据库连接配置
每个微服务的环境变量中添加数据库用户名和密码,同时补充JDBC参数解决SSL、密钥检索及时区问题:
以accounts服务为例,其他微服务同理:
environment: SPRING_APPLICATION_NAME: "accounts" SPRING_DATASOURCE_URL: "jdbc:mysql://accountsdb:3306/accountsdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" SPRING_DATASOURCE_USERNAME: "root" SPRING_DATASOURCE_PASSWORD: "root"
4. 统一微服务网络配置
让所有微服务继承common-config.yml中的microservice-base-config,保证网络配置与数据库服务一致:
比如accounts服务修改为:
accounts: image: "xyz/accounts" container_name: accounts-ms ports: - "8080:8080" environment: SPRING_APPLICATION_NAME: "accounts" SPRING_DATASOURCE_URL: "jdbc:mysql://accountsdb:3306/accountsdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" SPRING_DATASOURCE_USERNAME: "root" SPRING_DATASOURCE_PASSWORD: "root" extends: file: common-config.yml service: microservice-base-config depends_on: accountsdb: condition: service_healthy
修改后的完整配置文件
common-config.yml
services: network-deploy-service: networks: - xyz microservice-db-config: extends: service: network-deploy-service image: mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "0.0.0.0", "-u", "root", "-proot"] timeout: 10s retries: 10 interval: 10s start_period: 30s environment: MYSQL_ROOT_PASSWORD: root MYSQL_ROOT_HOST: "%" microservice-base-config: extends: service: network-deploy-service deploy: resources: limits: memory: 700m
docker-compose.yml
services: accountsdb: container_name: accountsdb ports: - 3307:3306 environment: MYSQL_DATABASE: accountsdb extends: file: common-config.yml service: microservice-db-config loansdb: container_name: loansdb ports: - 3308:3306 environment: MYSQL_DATABASE: loansdb extends: file: common-config.yml service: microservice-db-config cardsdb: container_name: cardsdb ports: - 3309:3306 environment: MYSQL_DATABASE: cardsdb extends: file: common-config.yml service: microservice-db-config accounts: image: "xyz/accounts" container_name: accounts-ms ports: - "8080:8080" environment: SPRING_APPLICATION_NAME: "accounts" SPRING_DATASOURCE_URL: "jdbc:mysql://accountsdb:3306/accountsdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" SPRING_DATASOURCE_USERNAME: "root" SPRING_DATASOURCE_PASSWORD: "root" extends: file: common-config.yml service: microservice-base-config depends_on: accountsdb: condition: service_healthy loans: image: "xyz/loans" container_name: loans-ms ports: - "8090:8090" environment: SPRING_APPLICATION_NAME: "loans" SPRING_DATASOURCE_URL: "jdbc:mysql://loansdb:3306/loansdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" SPRING_DATASOURCE_USERNAME: "root" SPRING_DATASOURCE_PASSWORD: "root" extends: file: common-config.yml service: microservice-base-config depends_on: loansdb: condition: service_healthy cards: image: "xyz/cards" container_name: cards-ms ports: - "9000:9000" environment: SPRING_APPLICATION_NAME: "cards" SPRING_DATASOURCE_URL: "jdbc:mysql://cardsdb:3306/cardsdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" SPRING_DATASOURCE_USERNAME: "root" SPRING_DATASOURCE_PASSWORD: "root" extends: file: common-config.yml service: microservice-base-config depends_on: cardsdb: condition: service_healthy networks: xyz: driver: "bridge"
内容的提问来源于stack exchange,提问作者Sanat Pandey
相关产品推荐
相关产品推荐

