docker在使用spring-boot mysql-docker时的编写问题

c86crjj0  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(356)

我在尝试运行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有问题吗?

6tqwzwtp

6tqwzwtp1#

除了@shawrup对正在发生的事情的出色描述之外,另一个解决方案是添加 healtcheck 到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
dwthyt8l

dwthyt8l2#

这里的问题是,您的应用程序试图在准备就绪之前连接到mysql。根据官方文件
您可以使用depends\u on选项控制服务启动和关闭的顺序。compose总是按依赖顺序启动和停止容器,其中依赖项由依赖项、链接、卷和网络模式决定:“service:...".
但是,对于startup来说,compose不会等到容器“就绪”(无论对于您的特定应用程序意味着什么)时才开始—只会等到它运行时才开始。这是有充分理由的。
等待数据库(例如)准备就绪的问题实际上只是分布式系统中更大问题的一个子集。在生产环境中,您的数据库可能随时不可用或移动主机。您的应用程序需要能够抵御这些类型的故障。
要处理此问题,请将应用程序设计为在发生故障后尝试重新建立与数据库的连接。如果应用程序重试连接,它最终可以连接到数据库。
使用诸如wait for it、dockerize、sh compatible wait for或relayandcontainers template之类的工具。这些是一些小的 Package 脚本,您可以将它们包含在应用程序的映像中,以轮询给定的主机和端口,直到它接受tcp连接。
从这里开始。
我发现,如果db连接失败,SpringBoot2.3.4不会停止你的应用程序。如果应用程序尝试访问数据库,它将重试;如果数据库已打开,则将建立连接。
另一个解决方法是,先启动db,然后启动应用程序。

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

相关问题