Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用spring boot mysql docker时出现docker编写问题_Java_Mysql_Spring Boot_Docker_Docker Compose - Fatal编程技术网

Java 使用spring boot mysql docker时出现docker编写问题

Java 使用spring boot mysql docker时出现docker编写问题,java,mysql,spring-boot,docker,docker-compose,Java,Mysql,Spring Boot,Docker,Docker Compose,我在尝试运行docker compose时遇到此异常 app-server_1 | com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure app-server_1 | app-server_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not r

我在尝试运行docker compose时遇到此异常

app-server_1  | com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
app-server_1  | 
app-server_1  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
我的docker-compose.yml看起来像这样

version: "3.7"

services:
  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_DATABASE: ppmt
      MYSQL_USER: vilius
      MYSQL_PASSWORD: vilius123
      MYSQL_ROOT_PASSWORD: root
    networks:
      - backend

  app-server:
    build:
      context: simple-fullstack
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    restart: always
    depends_on:
      - db
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/ppmt?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
      SPRING_DATASOURCE_USERNAME: vilius
      SPRING_DATASOURCE_PASSWORD: vilius123
    networks:
      - backend

networks:
  backend:
应用程序属性

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url =jdbc:mysql://db:3306/ppmt?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=vilius
spring.datasource.password=vilius123

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.initialize=true

已经挣扎了一段时间,看到人们有类似的问题,但仍然没有找到解决办法。我的docker compose.yml有问题吗?

这里的问题是,您的应用程序正在尝试在准备就绪之前连接到mysql。根据官方文件

您可以使用depends_on选项控制服务启动和关闭的顺序。Compose总是按照依赖关系顺序启动和停止容器,其中依赖关系由依赖关系、链接、卷和网络模式决定:“服务:…”

但是,对于启动,Compose不会等到容器“就绪”(无论对您的特定应用程序意味着什么)时才开始,而是等到它运行时才开始。这是有充分理由的

等待数据库(例如)准备就绪的问题实际上只是分布式系统更大问题的一个子集。在生产环境中,数据库可能随时不可用或移动主机。您的应用程序需要能够适应这些类型的故障

要处理此问题,请将应用程序设计为在出现故障后尝试重新建立与数据库的连接。如果应用程序重试连接,它最终可以连接到数据库

使用工具,如wait wait、dockerize、sh compatible wait for或RelayAndContainers模板。这些是小包装脚本,您可以将其包含在应用程序的映像中,以轮询给定的主机和端口,直到它接受TCP连接

我发现,如果db连接失败,SpringBoot2.3.4不会停止你的应用程序。如果应用程序尝试访问数据库,它将重试,如果数据库启动,则将建立连接

另一个解决方法是,先启动数据库,然后启动应用程序

docker-compose up db
docker-compose up app-server

除了@Shawrup对正在发生的事情的出色描述之外,另一个解决方案是在MySQL容器中添加一个。这将导致Docker Compose在启动任何依赖容器之前等待healthcheck成功

您的MySQL容器配置可能如下所示:

  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_DATABASE: ppmt
      MYSQL_USER: vilius
      MYSQL_PASSWORD: vilius123
      MYSQL_ROOT_PASSWORD: root
    networks:
      - backend
    healthcheck:
      test: "/usr/bin/mysql --user=root --password=root --execute \"SHOW DATABASES;\""
      interval: 2s
      timeout: 20s
      retries: 10

检查JDBCURL中的IP地址或主机名是否正确我的建议是包装JDBC:mysql。。。双引号中的字符串,因为:yamlI中的字符发现接受此答案很奇怪,因为app server定义中已指定dependens\u on:db。dependens\u on只是确保db在app server之前运行,并不意味着db将在app server启动之前准备好接受请求。明白了。更好的解决方案可能是使用wait-for-script()。否则,在我看来,使用docker compose没有什么意义。是的,答案中也提到了docker docs推荐的方法。我还添加了我的发现作为另一个选项。我还更改了spring容器,以便在失败时重新启动它,因为Dependes\u on仅确保db将启动,但大多数时候db的加载速度不如spring project快,并导致链接失败。