docker-compose 中 depends_on 的作用

2023-09-14 18:15:00

depends_on 介绍

在 Docker Compose 中,depends_on 是一个用于定义服务之间依赖关系的关键字。它允许您指定一个或多个服务依赖于其他服务,以确保在启动或重新创建容器时,所依赖的服务先于依赖它们的服务启动。

以下是一些关于 depends_on 的详解:

  1. 启动顺序:通过在服务的配置中使用 depends_on,您可以告诉 Docker Compose 在启动容器时按照指定的顺序启动服务。例如,如果服务 A 依赖于服务 B 和服务 C,则在启动时,Docker Compose 会先启动服务 B 和服务 C,然后才会启动服务 A。
  2. 仅表示依赖关系:depends_on 只表示依赖关系,而不会等待依赖的服务完全可用。它只确保在依赖的服务启动后再启动当前服务。因此,依赖的服务可能仍在进行初始化或准备阶段,而不一定已经完全可用。如果需要等待服务完全可用,可以结合使用其他工具或技术,例如健康检查或等待脚本。
  3. 无法保证健康状态:depends_on 并不能保证依赖的服务在启动后处于健康状态。它只负责在启动时按照指定顺序启动服务,但并不检查服务的健康状态或等待服务变为可用状态。对于检查服务健康状态,可以使用其他机制,例如使用健康检查命令或工具。
  4. 并行启动:默认情况下,Docker Compose 会尽可能并行启动服务,而不是完全按照 depends_on 指定的依赖关系顺序启动。这是因为 Docker Compose 会尝试最大化容器的并发启动,以提高启动效率。如果需要强制按照依赖关系顺序启动,请使用 depends_on 结合 restart 关键字的 condition: ["service_started"] 选项。

综上所述,depends_on 关键字允许您定义 Docker Compose 服务之间的依赖关系,但它并不能保证服务的可用性或健康状态。

docker-compose.yml 样例文件

version: '3'

services:
  rabbitmq:
    hostname: rabbitmq_host
    container_name: 'mq'
    image: rabbitmq:3.9.11-management
    restart: always
    ports:
      - "5772:5672"  # AMQP
      - "15772:15672"  # Web UI
    networks:
      - app-network
    environment:
      RABBITMQ_DEFAULT_USER: root
      RABBITMQ_DEFAULT_PASS: pwd
      RABBITMQ_DEFAULT_VHOST: /
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq/mnesia

    healthcheck:
      test: [ "CMD", "rabbitmq-diagnostics", "ping" ]
      interval: 50s
      timeout: 5s
      retries: 3


  selenium:
    container_name: 'selenium'
    image: selenium/standalone-chrome
    restart: always
    ports:
      - "4444:4444"

    networks:
      - app-network

    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:4444/wd/hub/status" ]
      interval: 30s
      timeout: 5s
      retries: 3


  db:
    container_name: 'mysql8'
    image: mysql:8.0.32
#    hostname: mysql_host
    user: root
    command:
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci

    environment:
      LANG: C.UTF-8
      MYSQL_ROOT_PASSWORD: pwd
      MYSQL_DATABASE: yinlian

    ports:
      - "3306:3306"

    volumes:
      - "./data/db/data:/var/lib/mysql"
      - "./data/db/mysql-files:/var/lib/mysql-files"
      - "./build/docker/mysqldb/my.cnf:/etc/my.cnf"

    networks:
      - app-network

    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
      interval: 30s
      timeout: 5s
      retries: 3

  app-producer:
    container_name: 'producer'
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8001:8001"

    command: ['echo','hello world, Frank']
    depends_on:
      - db
      - rabbitmq
      - selenium

    networks:
      - app-network


networks:
  app-network:
    driver: bridge

volumes:
  rabbitmq_data:
    driver: local

上面的 文件中定义了 rabbitmq , db, selenium ,以及 app-producer , 其中 app-producer 服务 依赖于 其他三个服务, 这个时候如何进行配置呢?

depends_on 只能保证启动的顺序.

那么如何解决 保证 服务启动后,才启动app-producer 服务呢? 为此需要 使用长定义模式

depends_on 有一个长定义模式

Long syntax

The long form syntax enables the configuration of additional fields that can’t be expressed in the short form.

  • restart: When set to true Compose restarts this service after it updates the dependency service. This applies to an explicit restart controlled by a Compose operation, and excludes automated restart by the container runtime after the container dies.
  • condition: Sets the condition under which dependency is considered satisfied
    • service_started: An equivalent of the short syntax described above
    • service_healthy: Specifies that a dependency is expected to be “healthy” (as indicated by healthcheck) before starting a dependent service.
    • service_completed_successfully: Specifies that a dependency is expected to run to successful completion before starting a dependent service.
  • required: When set to false Compose only warns you when the dependency service isn’t started or available. If it’s not defined the default value of required is true.

condition 说明

下面的文件中 我定义了一个web , db 服务, 此时 web 服务 启动就需要等待 db启动 并且成功后,才能启动.

condition 的含义 service_healthy 做健康检查

service_completed_successfully 表示 容器正常退出了, 之后 才进行启动.

service_started 只保证启动顺序, 并不做任何检查.

services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:latest
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 3s
      retries: 3

service_completed_successfully 参数是长定义语法中的一个字段,用于指定依赖服务在成功完成后,才启动相关的服务。

当将 service_completed_successfully 设置为 true 时,它表示依赖服务必须完全运行并成功完成(即退出状态码为 0),才能启动相关的服务。

让我们通过一个示例来说明该参数的含义。假设我们有一个应用程序,其中包含一个 worker 服务和一个 db_migration 服务。我们希望在启动 worker 服务之前,先运行 db_migration 服务,并确保 db_migration 服务成功完成数据库迁移操作。

使用长定义语法,我们可以将 depends_on 部分扩展为以下形式:

services:
  worker:
    build: .
    depends_on:
      db_migration:
        condition: service_completed_successfully

  db_migration:
    build: .
    command: ./run_migration.sh

在上述示例中,我们在 worker 服务的 depends_on 部分使用长定义语法来定义 db_migration 服务的依赖。通过将 condition 字段设置为 service_completed_successfully,我们指定了 worker 服务依赖于 db_migration 服务成功完成。

当我们使用 Docker Compose 启动应用程序时,Compose 将先运行 db_migration 服务,并等待其成功完成(即退出状态码为 0)。一旦 db_migration 服务成功完成,Compose 将启动 worker 服务。

通过使用 service_completed_successfully 参数,我们可以确保依赖服务在成功完成后,再启动相关的服务。这对于需要在依赖服务成功完成后才能进行后续操作的场景非常有用,如数据库迁移、初始化脚本等。

service_started 这个只是表示启动顺序,并不能保证健康状态.

service_healthyservice_completed_successfully 是长定义语法中用于定义依赖服务的两个不同条件。

  • service_healthy:这个条件要求依赖服务处于健康状态(由健康检查指定),才会启动相关的服务。通过设置 condition: service_healthy,Compose 将等待依赖服务的健康状态后再启动相关服务。健康状态通常是通过在容器中运行健康检查命令或脚本来确定的,例如检查 HTTP 响应或数据库连接等。
  • service_completed_successfully:这个条件要求依赖服务成功完成(即退出状态码为 0),才会启动相关的服务。通过设置 condition: service_completed_successfully,Compose 将等待依赖服务成功完成后再启动相关服务。这通常用于需要确保特定操作或任务在依赖服务完成后才能进行的情况,例如数据库迁移、初始化脚本等。

总结一下它们的区别:

  • service_healthy 关注依赖服务的健康状态,它要求依赖服务处于健康状态才能启动相关服务。
  • service_completed_successfully 关注依赖服务的成功完成,它要求依赖服务在成功完成后(即退出状态码为 0)才能启动相关服务。

required 说明

在长定义语法中,required 字段用于指定依赖服务是否是必需的。它控制了当依赖服务未启动或不可用时的行为。

  • required 设置为 true默认值),如果依赖服务未启动或不可用,Compose 将阻止启动相关的服务,并显示警告信息。
  • required 设置为 false,Compose 仍会显示警告信息,但不会阻止启动相关的服务。相当于它是可选的,即使依赖服务未启动或不可用,相关服务仍会尝试启动。
services:
  web:
    build: .
    depends_on:
      database:
        required: false

  database:
    image: mysql:latest

下面看看一个完整的例子 docker-compose-test.yml:

version: '3'

services:
  rabbitmq:
    hostname: rabbitmq_host
    container_name: 'mq'
    image: rabbitmq:3.9.11-management
    restart: always
    ports:
      - "5772:5672"  # AMQP
      - "15772:15672"  # Web UI
    networks:
      - app-network
    environment:
      RABBITMQ_DEFAULT_USER: root
      RABBITMQ_DEFAULT_PASS: pwd
      RABBITMQ_DEFAULT_VHOST: /
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq/mnesia

    healthcheck:
      test: [ "CMD", "rabbitmq-diagnostics", "ping" ]
      interval: 50s
      timeout: 5s
      retries: 3


  selenium:
    container_name: 'selenium'
    image: selenium/standalone-chrome
    restart: always
    ports:
      - "4444:4444"

    networks:
      - app-network

    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:4444/wd/hub/status" ]
      interval: 30s
      timeout: 5s
      retries: 3


  db:
    container_name: 'mysql8'
    image: mysql:8.0.32
#    hostname: mysql_host
    user: root
    command:
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci

    environment:
      LANG: C.UTF-8
      MYSQL_ROOT_PASSWORD: pwd
      MYSQL_DATABASE: yinlian

    ports:
      - "3306:3306"

    volumes:
      - "./data/db/data:/var/lib/mysql"
      - "./data/db/mysql-files:/var/lib/mysql-files"
      - "./build/docker/mysqldb/my.cnf:/etc/my.cnf"

    networks:
      - app-network

    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
      interval: 30s
      timeout: 5s
      retries: 3

  app-producer:
    container_name: 'producer'
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8001:8001"

    command: ['echo','hello world, Frank']
    depends_on:
      db:
        condition: service_healthy

      rabbitmq:
        condition: service_healthy

      selenium:
        condition: service_healthy

    networks:
      - app-network


networks:
  app-network:
    driver: bridge

volumes:
  rabbitmq_data:
    driver: local

请添加图片描述

请添加图片描述

如果 依赖服务启动失败了, app-producer 就不会启动 ,直接退出了

请添加图片描述

参考文档

depends_on

分享快乐,留住感动. '2023-09-13 19:17:03' --frank
更多推荐

【2023,学点儿新Java-02】计算机硬件与软件 | CPU、内存、硬盘概览 | 科学使用键盘——“指法” | 软件——计算机的灵魂 | 人机交互方式

前情回顾:【2023,学点儿新Java-01】从查看本机jdk版本开始|Java基础全程脉络图、Java工程师全程技术路线、Java职业晋升路线图我们见到的太阳是八分钟前的太阳,见到的月亮是一点三秒之前的月亮,见到一英里之外的建筑,是五微秒之前存在的,即使你在我一米之外,我见到的也是三纳米秒以前的你,我们所眼见的都是过

华为云云耀云服务器L实例评测|基于L实例使用Docker部署MySQL服务并连接MySQL—phpMyAdmin管理工具

文章目录一、云耀云服务器产品优势1、智能不卡顿2、价优随心用3、上手更简单4、管理更省心二、远程连接云耀云服务器L实例三、安装Docker、docker-compse1、docker安装2、docker-compose安装四、方法①使用Docker安装部署MySQL服务五、方法②使用docker-compse安装部署M

ELK 企业级日志分析系统

ELK概述:1、ELK简介ELK平台是一套完整的日志集中处理解决方案,将ElasticSearch、Logstash和Kiabana三个开源工具配合使用,完成更强大的用户对日志的查询、排序、统计需求。●ElasticSearch:是基于Lucene(一个全文检索引擎的架构)开发的分布式存储检索引擎,用来存储各类日志。E

免杀对抗-Python-混淆算法+反序列化-打包生成器-Pyinstall

Python-MSF/CS生成shellcode-上线cs上线1.生成shellcode-c或者python2.打开pycharm工具,创建一个py文件,将原生态执行代码复制进去shellcode执行代码:importctypesfromdjango.contrib.gisimportptr#cs#shellcode=

完整指南:使用JavaScript从零开始构建中国象棋游戏

引言中国象棋,又被称为国际象棋,是一款起源于中国的古老棋类游戏。本文旨在为大家提供一个简单明了的步骤,教你如何使用JavaScript从零开始构建这款经典的棋类游戏。1.游戏简介在中国象棋中,两方各有一军队,包括士、象、车、马、炮和卒等棋子,目标是将对方的“将”或“帅”给将死,达到胜利。2.准备工作首先,确保你的开发环

文举论金:黄金原油全面走势分析

市场没有绝对,涨跌没有定势,所以,对市场行情的涨跌平衡判断就是你的制胜法宝。欲望!有句意大利谚语:让金钱成为我们忠心耿耿的仆人,否则,它就会成为一个专横跋扈的主人。空头,多头都能赚钱,唯有贪心不能赚。是你掌控欲望还是欲望掌控你?古人云:不积硅步无以至千里,不积小流无以成江海。希望这句话成为我们之间的共勉。自知!人贵自知

SpringCloud:Feign实现微服务之间相互请求

文章目录🎉欢迎来到架构设计专栏~SpringCloud:Feign实现微服务之间相互请求☆*o(≧▽≦)o*☆嗨~我是IT·陈寒🍹✨博客主页:IT·陈寒的博客🎈该系列文章专栏:架构设计📜其他专栏:Java学习路线Java面试技巧Java实战项目AIGC人工智能数据结构学习🍹文章作者技术和水平有限,如果文中出现

Go的并发的退出

有时候我们需要通知goroutine停止它正在干的事情,比如一个正在执行计算的web服务,然而它的客户端已经断开了和服务端的连接。Go语言并没有提供在一个goroutine中终止另一个goroutine的方法,由于这样会导致goroutine之间的共享变量落在未定义的状态上。在8.7节中的rocketlaunch程序中

什么是区块链,解释区块链的原理和应用场景

1、什么是区块链,解释区块链的原理和应用场景。区块链是一种分布式数据库,它由一系列按照时间顺序排列的数据块组成,并采用密码学方式保证不可篡改和不可伪造。区块链技术最初起源于比特币,作为比特币的底层技术,用于去中心化和去信任地维护一个可靠的数据库。相比于传统的网络,区块链具有数据难以篡改和去中心化的两大核心特点,使得区块

【数据库入门到精通】mysql的存储过程实战

前言🏠个人主页:我是沐风晓月🧑个人简介:大家好,我是沐风晓月,双一流院校计算机专业,阿里云社区专家博主😉😉💕座右铭:先努力成长自己,再帮助更多的人,一起加油进步🍺🍺🍺💕欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信😘可以关注我的云原生社区:云原生社区也可以关注我的英语社区:

Input子系统 - Kernel驱动程序 - Android

Input子系统-Kernel驱动程序-Android1、Input子系统相关定义1.1代码位置1.2input_dev结构体:表示输入设备1.3input_handler结构体:structinput_handler-implementsoneofinterfacesforinputdevices1.4input_h

热文推荐