上篇回顾

  • 本文是《docker-compose下的java应用启动顺序两部曲》的终篇,在上一篇《docker-compose下的java应用启动顺序两部曲之一:问题分析》中,我们以SpringCloud环境下的注册中心和业务服务为例,展示了docker-compose.yml中depends_on参数的不足:即只能控制容器创建顺序,但我们想要的是eureka服务就绪之后再启动业务服务,并且docker官方也认为depends_on参数是达不到这个要求的,如下图所示:
    在这里插入图片描述
  • 针对上述问题,docker给出的解决办法是使用wait-for-it.sh脚本来解决问题,地址:upload/201911041555283357.png" alt="在这里插入图片描述" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" />

    什么是wait-for-it.sh

  • wait-for-it.sh脚本用来访问指定的地址和端口,如果收不到响应就等待一段时间再去重试,直到收到响应后,再去做前面指定好的命令,如上图红框所示./wait-for-it.sh db:5432 -- python app.py的意思是:等到db:5432这个远程访问能够响应的时候,就去执行python app.py命令
  • wait-for-it.sh文件的链接:
    https://raw.githubusercontent.com/zq2599/blog_demos/master/wait-for-it-demo/docker/wait-for-it.sh

    环境信息

    本次实战的环境如下:
  1. 操作系统:CentOS Linux release 7.7.1908
  2. docker:1.13.1
  3. docker-compose:1.24.1
  4. spring cloud:Finchley.RELEASE
  5. maven:3.6.0
  6. jib:1.7.0

实战简介

上一篇的例子中,我们用到了eureka和service两个容器,eureka是注册中心,service是普通业务应用,service容器向eureka容器注册时,eureka还没有初始化完成,因此service注册失败,在稍后的自动重试时由于eureka进入ready状态,因而service注册成功。
今天我们来改造上一篇的例子,让service用上docker官方推荐的wait-for-it.sh脚本,等待eureka服务就绪再启动java进程,确保service可以一次性注册eureka成功;
为了达到上述目标,总共需要做以下几步:

  1. 简单介绍eureka和service容器的镜像是怎么制作的;
  2. 制作基础镜像,包含wait-for-it.sh脚本;
  3. 使用新的基础镜像构建service镜像;
  4. 改造docker-compose.yml;
  5. 启动容器,验证顺序控制是否成功;
  6. wait-for-it.sh方案的缺陷;

接下来进入实战环节;

源码下载

如果您不想编码,也可以在GitHub上获取文中所有源码和脚本,地址和链接信息如下表所示:
| 名称 | 链接 | 备注|
| :-------- | :----| :----|
| 项目主页| https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
| git仓库地址(https)| https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
| git仓库地址(ssh)| git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
 

这个git项目中有多个文件夹,本章的应用在wait-for-it-demo文件夹下,如下图红框所示:
在这里插入图片描述
源码的结构如下图所示:
在这里插入图片描述
接下来开始编码了;

简单介绍eureka和service容器

上一篇和本篇,我们都在用eureka和service这两个容器做实验,现在就来看看他们是怎么做出来的:

  1. eureka是个maven工程,和SpringCloud环境中的eureka服务一样,唯一不同的是它的pom.xml中使用了jib插件,用来将工程构建成docker镜像:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="upload/201911041555547331.png" alt="在这里插入图片描述" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" />
至此,service工程改造完毕,接下来修改docker-compose.yml,让service容器能用上wait-for-it.sh
### 改造docker-compose.yml

  1. 完整的docker-compose.yml内容如下所示:
version: '3' services:  eureka:    image: bolingcavalry/eureka:0.0.1-SNAPSHOT    container_name: eureka    restart: unless-stopped  service:    image: bolingcavalry/service:0.0.1-SNAPSHOT    container_name: service    restart: unless-stopped    command: sh -c './wait-for-it.sh eureka:8080 -t 0  -- java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication'    depends_on:    - eureka
  1. 注意command参数的内容,如下,service容器创建后,会一直等待eureka:8080的响应,直到该地址有响应后,才会执行命令java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication