depends_on 解决 docker 容器依赖问题

news2024/11/24 11:53:02

如果你经常使用docker-compose启动服务的话,可能会遇到下面的问题:服务 B 依赖服务 A,需要服务 A 先启动,再启动服务 B

举个例子,在部署 kafka 集群的时候,需要启动两个kafka,并使用zookeeper做注册中心,docker-compose.yaml 文件如下

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    networks:
      - kafka_net
  kafka1:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka1
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      # 对应 server.properties 中 advertised.listeners 配置
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
      # 对应 server.properties 中 listeners 配置
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka1:/kafka
    networks:
      - kafka_net
  kafka2:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka2
    ports:
      - "9093:9092"
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka2:/kafka
    networks:
      - kafka_net

networks:
  kafka_net:
    driver: bridge

此时会同时启动 3 个容器,zookeeper、kafka1 和 kafka2

$ docker-compose up -d
[+] Running 3/3
 ⠿ Container kafka1     Started                                                                            11.6s
 ⠿ Container kafka2     Started                                                                            11.5s
 ⠿ Container zookeeper  Started                                                                            11.5s

使用docker logs查看kafka1启动日志

$ docker logs kafka1
...
[2023-05-06 02:20:49,851] FATAL [Kafka Server 1], Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
java.lang.RuntimeException: A broker is already registered on the path /brokers/ids/1. This probably indicates that you either have configured a brokerid that is already in use, or else you have shutdown this broker and restarted it faster than the zookeeper timeout so it appears to be re-registering.
	at kafka.utils.ZkUtils.registerBrokerInZk(ZkUtils.scala:417)
	at kafka.utils.ZkUtils.registerBrokerInZk(ZkUtils.scala:403)
	at kafka.server.KafkaHealthcheck.register(KafkaHealthcheck.scala:70)
	at kafka.server.KafkaHealthcheck.startup(KafkaHealthcheck.scala:50)
	at kafka.server.KafkaServer.startup(KafkaServer.scala:280)
	at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:38)
	at kafka.Kafka$.main(Kafka.scala:65)
	at kafka.Kafka.main(Kafka.scala)
[2023-05-06 02:20:49,854] INFO [Kafka Server 1], shutting down (kafka.server.KafkaServer)
[2023-05-06 02:20:49,860] INFO [Socket Server on Broker 1], Shutting down (kafka.network.SocketServer)
[2023-05-06 02:20:49,874] INFO [Socket Server on Broker 1], Shutdown completed (kafka.network.SocketServer)
...

日志抛出了个timeout异常,连接zookeeper超时了,这是因为在启动kafka1的时候,zookeeper还没启动完成,kafka1 在连接 zookeeper 的时候,就会报连接超时

这时候我们可以用depends_on来解决容器依赖问题,depends_on表示在启动本容器前,确保depends_on的容器先启动

加上depends_on后的docker-compose.yaml文件如下

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    networks:
      - kafka_net
  kafka1:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka1
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      # 对应 server.properties 中 advertised.listeners 配置
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
      # 对应 server.properties 中 listeners 配置
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka1:/kafka
    depends_on:
      - zookeeper
    networks:
      - kafka_net
  kafka2:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka2
    ports:
      - "9093:9092"
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka2:/kafka
    depends_on:
      - zookeeper
    networks:
      - kafka_net

networks:
  kafka_net:
    driver: bridge

再次启动服务

$ docker-compose up -d 
[+] Running 3/3
 ⠿ Container zookeeper  Started                                                                             0.5s
 ⠿ Container kafka2     Started                                                                             0.9s
 ⠿ Container kafka1     Started                                                                             1.0s

docker logs查看kafka启动日志,发现容器正常启动

到这里我们已经解决了容器的启动顺序问题,但是多启动几次会发现,kafka连接zookeeper超时的问题还是会发生,而且是偶发性的,这是为什么呢?查阅资料发现,**depends_on**只是解决容器启动顺序的问题,但是无法保证容器启动完成,或者说并不会等待**zookeeper**就绪就直接启动**kafka**,这时候如果zookeeper还在启动中,kafka就发起连接请求,此时请求就会超时

解决方案是在depends_on中加入condition属性,conditon能使用下面三种状态

  • serveice_started: 容器启动完成
  • service_healthy:容器处于healthy状态,healthy状态的检查依赖healthcheck
  • service_completed_successfully:在启动依赖服务之前,需要确保依赖服务已经成功完成运行

这里我们使用service_healthy,当zookeeper处于healthy状态的时候,再启动kafka

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    networks:
      - kafka_net
  kafka1:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka1
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      # 对应 server.properties 中 advertised.listeners 配置
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
      # 对应 server.properties 中 listeners 配置
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka1:/kafka
    depends_on:
      zookeeper:
        condition: service_healthy
    networks:
      - kafka_net
  kafka2:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka2
    ports:
      - "9093:9092"
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka2:/kafka
    depends_on:
      zookeeper:
        condition: service_healthy
    networks:
      - kafka_net

networks:
  kafka_net:
    driver: bridge

启动服务试一下

$ docker-compose up -d
[+] Running 3/4
 ⠿ Network kafka_kafka_net  Created                                                                         0.0s
 ⠿ Container zookeeper      Waiting                                                                         1.0s
 ⠿ Container kafka1         Created                                                                         0.1s
 ⠿ Container kafka2         Created                                                                         0.1s
container for service "zookeeper" has no healthcheck configured

这里提示zookeeper服务没有配置healthcheck,这是因为,docker 只能启动服务,并不知道容器内的进程什么时候处于healthy状态,所以需要我们自己配置健康检查,不同的进程有不同的健康检查方法,检查zookeeper是否正常启动完成,可以执行echo 'stat' | nc localhost 2181 || exit 1命令,命令返回 0 表示容器healthy,返回 1 表示unhealthyhealthy还能配置其他参数,如时间间隔、超时等,完整的配置如下

version: '3'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    networks:
      - kafka_net
    healthcheck:
      test: echo 'stat' | nc localhost 2181 || exit 1
      interval: 5s
      timeout: 5s
      retries: 6
  kafka1:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka1
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      # 对应 server.properties 中 advertised.listeners 配置
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
      # 对应 server.properties 中 listeners 配置
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka1:/kafka
    depends_on:
      zookeeper:
        condition: service_healthy
    networks:
      - kafka_net
  kafka2:
    image: wurstmeister/kafka:2.11-0.11.0.3
    container_name: kafka2
    ports:
      - "9093:9092"
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_PORT: 9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - ./data/kafka2:/kafka
    depends_on:
      zookeeper:
        condition: service_healthy
    networks:
      - kafka_net

networks:
  kafka_net:
    driver: bridge
$ docker-compose up -d
[+] Running 4/4
 ⠿ Network kafka_kafka_net  Created                                                                         0.0s
 ⠿ Container zookeeper      Healthy                                                                         6.0s
 ⠿ Container kafka1         Started                                                                         6.5s
 ⠿ Container kafka2         Started                                                                         6.4s

可以看到,kafka会等待zookeeper启动,并处于healthy状态,再启动

到这里我们已经彻底解决docker容器依赖问题啦,如果喜欢我的文章的话可以关注公众号:huangxy,不定期分享技术知识

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/566868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于云计算和物联网技术开发的智慧校园云平台源码

智慧校园系统是利用物联网和云计算,强调对教学、科研、校园生活和管理的数据采集、智能处理、为管理者和各个角色按需提供智能化的数据分析、教学、学习的智能化服务环境。它包含“智慧环境、智慧学习、智慧服务、智慧管理”等层面的内容。 文末获取联系 它描绘的是…

准备搞个大动作!

目前我们的会员群的同学越来越多,然后我们提供的内容已经从起步篇,趣味篇,工具篇到高级篇了。但是到了高级篇很多内容都跟编程相关,有一点门槛,如果单单看文字是肯定无法满足大家的需求。为了更好的服务大家&#xff0…

跃升数字生产力,九州云受邀出席闵行国际人才月

5月22日,由闵行人才工作领导小组办公室指导、中共闵行区马桥镇委员会及闵行区马桥镇人民政府主办、上海人工智能研究院协办的首届“大零号湾”国际人才月马桥人工智能周成功召开。 本届大会以“AI才共赢 智敬未来”为主题,探讨科技创新的最新动态和趋势&…

如何使用Linux Top命令

Linux中的top命令允许您监视当前正在运行的进程及其使用的系统资源。作为系统管理员,它可能是工具箱中最有用的工具,特别是如果您知道如何使用它的话。所有Linux发行版都预装了top实用程序。通过这个交互式命令,您可以自定义如何浏览进程列表…

电脑蓝屏该如何给电脑重装系统

电脑蓝屏问题是让人头疼的常见故障之一,而重装系统是解决蓝屏问题的有效方法。本文将为您详细介绍如何在电脑蓝屏的情况下进行系统重装,轻松摆脱蓝屏困扰。 工具/原料: 系统版本:windows10系统 品牌型号:华为MateBoo…

常见的黄金期货交易风险包含哪些内容?

黄金期货交易作为受市场欢迎的投资理财方式,兼具高风险和高收益并存的特性。黄金期货交易风险也同样存在,那常见的黄金期货交易风险包含哪些内容? 黄金期货交易风险一、市场风险 投资者在黄金期货交易中,主要的风险来源于市场价格…

快来试试!免费用上GPT-4 !!!

GPT-4 简介 GPT-4是OpenAI上个月推出的最新人工智能语言模型,它可以根据给定的文本或关键词生成各种类似于人类语言甚至超越人类语言的文本,例如文章、故事、诗歌、代码、对话等。 GPT-4拥有1750亿个参数,是目前最大的语言模型之一&#xf…

红米8a,刷机到安卓调用之路

什么是BL锁? https://baijiahao.baidu.com/s?id1614459630284912892&wfrspider&forpc bl锁简单来说,就是厂商为了自己的目的,为了避免刷机,而人为设置的一道障碍,我的第一步就需要等待168小时,经…

随想011:关于编程

1945 年时,刚开始有计算机,那时候使用二进制数编程到了40年代末期,出现了汇编器,可以自动将汇编程序转换为二进制数序列1951 年 Grace Hopper 发明了编译器1957 年,Fortran,第一个高级语言,首次…

npm 无法下载 win32-x64-72_binding.node

使用npm安装node-sass时,其依赖了win32-x64-72_binding.node,但是一直提示“cannot download http://xxx/win32-x64-72_binding.node”,有两种方案可以解决,一种是在有私服的情况下,可以通过设置 SASS_BINARY_SITE 环境…

百度云原生数据库GaiaDB的HTAP与多地多活技术实践

​摘要:云原生数据库在使用存算分离技术后,可以在完全兼容MYSQL协议和语法的情况下,极大提升单实例所能承载的数据规模与吞吐能力上限。但除了对客户端兼容外,对整个数据生态(地域容灾,数据分析&#xff0c…

javaWebssh旅游论坛系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh旅游论坛系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Mye…

机器学习中四类进化算法的详解(遗传算法、差分进化算法、协同进化算法、分布估计算法)

1、遗传算法(Genetic Algorithm,GA) GA算法原理 首先我们来介绍进化算法的先驱遗传算法,遗传算法(Genetic Algorithm,简称GA)是一种最基本的进化算法,它是模拟达尔文生物进化理论的…

牛牛截图控件与利洽远程控制产品升级-支持证书自动升级

今天我们来聊一聊浏览器控件的一个痛点!看看我们是如何解决他的。 背景信息 目前市面上存在多种浏览器,IE、Chrome、Firefox、Edge以及一众国产浏览器,这些浏览器中,IE支持ActiveX,部分国产浏览器支持npapi&#xff…

vscode开发小程序项目并在微信开发者工具运行

需求:vscode开发uniapp之后在微信开发者工具运行,更改的时候微信开发者也同步更改 1.创建小程序命令 这里的uniapp-vue是项目名称,不能大写 vue create -p dcloudio/uni-preset-vue uniapp-vue 2.选择uni-app模版 有几种模版选择&#x…

Ubuntu TDengine 集成 EMQX 通过规则引擎实现设备数据直接入库

背景 曾使用过 IoTDB 自带的 MQTT Broker 实现了设备数据入库,那么使用 TDengine 时,我们可以借助 EMQX (一款优秀的国产开源 MQTT Broker )的规则引擎结合 TDengine 的 RESTful API 完成设备数据的路由与入库。 用到的工具 TD…

PAI-Diffusion中文模型全面升级,海量高清艺术大图一键生成

作者:段忠杰(终劫)、刘冰雁(伍拾)、汪诚愚(熊兮)、黄俊(临在) 背景 以Stable Diffusion模型为代表,AI生成内容(AI Generated Content&#xff…

鸿蒙Hi3861问题解决-[OHOS ERROR] clang not found, install it please

一、简介 在使用DevEco进行编译时出现[OHOS ERROR] clang not found, install it please问题,导致编译失败,这里做个问题记录。 二、解决 这种问题其实还是工具链安装不全造成的。 安装gn 这里用的是VSCode DevEco组件,里边包含了gn组件的安…

error while loading shared libraries: libc.so.6 误删除libc.so.6急救办法,

故障原因: 在高版本的环境中编译了一个软件,然而在低版本系统中无法使用,缺少libc.so支持,然而在编译过程中误删除了 libc.so.6的软连接,rm /lib64/libc.so.6 删除后发现系统好多命令都无法使用了,悲催&#xff01…

国际最高级别认可!赛宁网安荣获CMMI5国际认证

​​近日,经国际权威机构评估,南京赛宁信息技术有限公司(简称:赛宁网安)顺利通过国际软件领域最高级别的CMMI五级(简称CMMI5)认证。荣获CMMI5证书,标志着赛宁网安在软件研发、软件成…