【问题标题】:Spring boot microservices and Docker, unable to connect to databaseSpring Boot微服务和Docker,无法连接数据库
【发布时间】: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


【解决方案1】:

您好 Spinarial,请添加 network 并将其全部收集到一个网络中

          version: "3.4"

         services:
            springMvcRestApi:
                image: springbootproject:0.0.1
                container_name: app
                networks:
                   - postgres
                      ports:
                   -  8085:8085
                depends_on:
                   - postgres
                   - pgadmin
                links:
                   - postgres
                environment:
                   SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/reactiveDbcd?createDatabaseIfNotExist=true
                   SPRING_DATASOURCE_USERNAME: postgres
                   SPRING_DATASOURCE_PASSWORD: 12345

         postgres:
            container_name: postgres
            image: postgres
         environment:
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: 12345
            PGDATA: /data/postgres
         volumes:
           - postgres:/data/postgres
         expose:
           - 5432
         ports:
           - 5432:5432
         networks:
           - postgres
         restart: unless-stopped

       pgadmin:
         container_name: pgadmin_container
         image: dpage/pgadmin4
         environment:
              PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org}
              PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
              PGADMIN_CONFIG_SERVER_MODE: 'False'
         volumes:
          - pgadmin:/root/.pgadmin

         ports:
            - "${PGADMIN_PORT:-80}:80"
         networks:
            - postgres
         restart: unless-stopped

     networks:
       postgres:
          driver: bridge

     volumes:
        postgres:
          pgadmin:








   

【讨论】:

  • 您好,我刚刚编辑了帖子。它似乎也不起作用,我开始认为这一定是 spring-boot 方面的问题,就像 spring-boot 无法解析容器名称一样
  • 如果你愿意,我可以分享我自己写的示例吗?
猜你喜欢
  • 2019-10-11
  • 2021-09-20
  • 2020-09-06
  • 2018-08-29
  • 1970-01-01
  • 2019-09-09
  • 2015-06-28
  • 2020-07-24
  • 2020-03-10
相关资源
最近更新 更多