【发布时间】:2021-05-15 11:04:12
【问题描述】:
我正在用微服务编写一个测试应用程序来学习 Spring Boot。我已经完成了该应用程序,并希望使用 docker/docker-compose 在 AWS 上部署它来托管每个微服务。
我无法将任何 Spring Boot 实例连接到他们的 Mysql 数据库。我已经卡了几天了,我看不出有什么问题。
这是我的 docker-compose.yml
version: "3.3"
services:
card_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "cards"
ports:
- "33061:3306"
auth_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "auth"
ports:
- "33062:3306"
market_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "market"
ports:
- "33063:3306"
user_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "user"
ports:
- "33064:3306"
adminer:
image: adminer
restart: always
ports:
- 8000:8080
user:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/services/user/target/cardmarket-user-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "user_mysql"
card:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/services/card/target/cardmarket-card-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "card_mysql"
market:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/services/market/target/cardmarket-market-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "market_mysql"
proxy:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/zuul-proxy/target/zuul-proxy-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
auth:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/zuul-proxy/zuul-proxy-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "auth_mysql"
这是我的每个 spring 数据源设置:
用户应用程序.properties
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://user_mysql:3306/user
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
市场应用程序.properties
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://market_mysql:3306/market
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
验证应用程序.properties
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://auth_mysql:3306/auth
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
卡申请.properties
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://card_mysql:3306/cards
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
我确定这是我遗漏或误解的小东西,但我不知道是什么。
编辑 1
我又进行了几次测试,但仍然无法找出问题所在。 我注释掉了除了 card 和 card_mysql 容器之外的所有内容。 spring boot 实例为每个可能的配置(使用 docker dns 名称、localhost、共享和网络 ip)抛出异常,它们似乎都不起作用。 这两个容器确实可以通信,我可以使用 dns 名称在它们之间 ping。
我将 docker-desktop 与 wsl 一起使用,并将我的容器部署在 wsl Ubuntu 20.04 上。我还没有在实际的 Linux 机器上尝试过。
我也尝试过使用wait-for-it.sh让spring boot实例等待mysql实例,它确实等待正确但异常仍然发生。
这里是 Spring Boot 异常触发器的部分内容:
2021-05-16 12:23:48.948 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-05-16 12:23:50.277 ERROR 1 --- [ main] 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.
...
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: 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.
...
Caused by: java.net.ConnectException: Connection refused (Connection refused)
编辑 2 我尝试只使用一个 spring boot 和 mysql 实例并使用网络链接它们,不幸的是异常仍然触发。两个容器仍然 ping 通。这是我用于此测试的 docker-compose:
version: "3.9"
services:
card_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "cards"
networks:
- "card_network"
card:
image: "openjdk:11"
restart: always
entrypoint: ["/app/wait-for-it.sh", "card_mysql:3306", "--", "java", "-jar", "/app/services/card/target/cardmarket-card-0.0.1-SNAPSHOT.jar"]
# entrypoint: ["/app/wait-for-it.sh", "card_mysql:3306", "--", "ping", "card_mysql"]
volumes:
- ./:/app
depends_on:
- "card_mysql"
networks:
- "card_network"
networks:
card_network: {}
【问题讨论】:
-
您正在为 mysql 公开端口号 33061、33062、33063 等。但是,在 spring 属性文件中,您只使用 3306。为每个服务适当地更改它并试一试。
-
@dossani 暴露的端口只对连接到主机的东西很重要。对于容器之间的连接,端口映射无关紧要。您将始终使用端口 3306。
-
您的代码以什么方式失败?您的应用程序很有可能在 MySQL 准备好之前启动。
depends_on几乎没用,因为它只是等待 container 启动; Docker 不知道应用程序是否准备就绪。您的代码应该具有连接数据库的重试逻辑。 -
我已经编辑了帖子。 spring boot 容器都有重启选项,还不够吗?
标签: spring-boot docker docker-compose