Docker容器技术Docker前后端知识交流分享

Docker-compose编排微服务顺序启动解决方案

2018-08-29  本文已影响80人  AaronSimon

一、前言

docker-compose可以方便组合多个 docker 容器服务, 但是, 当容器服务之间存在依赖关系时, docker-compose 并不能保证服务的启动顺序。docker-compose 中的 depends_on 配置是容器的启动顺序, 并不是容器中服务的启动顺序。本章将详细叙述如何解决 docker-compose 顺序启动微服务的问题。

二、解决方案

经过两天的努力,大致总结出了三种解决顺序启动微服务的方案:

下面我将详细的讲述第三种解决顺序启动问题的方案。部署的微服务清单如下:

服务名 端口 服务说明 依赖服务 启动优先级(优先级越高越先启动)
eureka-service 8100 服务注册与发现 --- 1
config-server 8101 配置中心 eureka-server 2
apigateway 8102 网关服务 eureka-server,config-server 3
admin 8103 监控服务 eureka-server,config-server 3

2.1 各微服务镜像构建配置

由于各微服务的镜像构建配置差不多,这里只列举配置中心的配置:

            <!-- Docker maven plugin -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <imageName>simon/${project.artifactId}:${project.version}</imageName>
                    <!--<dockerDirectory>src/main/docker</dockerDirectory>-->
                    <forceTags>true</forceTags>
                    <baseImage>java</baseImage>
                    <!--安装镜像所需要的软件-->
                    <runs>
                        <!--同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包-->
                        <run>["apt-get","update"]</run>
                        <!--安装netcat-->
                        <run>["apt-get","-y","install","netcat"]</run>
                    </runs>
                    <entryPoint>["java","-jar","/${project.build.finalName}.jar"]</entryPoint>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

runs标签表示在构建镜像的时候,会顺序执行标签run中的命令,因为后面顺序启动微服务需要镜像中包含netcat,所以在构建镜像的时候要进行安装。

2.2 检测服务是否启动的脚本entrypoint.sh

#!/bin/bash
#set -x
#******************************************************************************
# @file    : entrypoint.sh
# @author  : simon
# @date    : 2018-08-28 15:18:43
#
# @brief   : entry point for manage service start order
# history  : init
#******************************************************************************

: ${SLEEP_SECOND:=2}

wait_for() {
    echo Waiting for $1 to listen on $2...
    while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
}

declare DEPENDS
declare CMD

while getopts "d:c:" arg
do
    case $arg in
        d)
            DEPENDS=$OPTARG
            ;;
        c)
            CMD=$OPTARG
            ;;
        ?)
            echo "unkonw argument"
            exit 1
            ;;
    esac
done

for var in ${DEPENDS//,/}
do
    host=${var%:*}
    port=${var#*:}
    wait_for $host $port
done

eval $CMD
#避免执行完命令之后退出容器
tail -f /dev/null

这个脚本有 2 个参数,:

2.3 docker-compose.yml

#docker compose编排微服务脚本
version: "3"
services:
  # 指定服务名称
  simonEureka:
    image: simon/eureka-server:2.0.1-SNAPSHOT
    hostname: simonEureka
    ports:
      - "8100:8100"
  simonConfig:
    image: simon/config-server:2.0.1-SNAPSHOT
    hostname: simonConfig
    ports:
      - "8101:8101"
    depends_on:
      - simonEureka
    volumes:
      - "./entrypoint.sh:/entrypoint.sh"
    environment:
      SLEEP_SECOND: 4
    tty: true
    entrypoint: /entrypoint.sh -d simonEureka:8100 -c 'java -jar config-server.jar';
  apigateway:
    image: simon/apigateway:2.0.1-SNAPSHOT
    ports:
      - "8102:8102"
    depends_on:
      - simonEureka
      - simonConfig
    volumes:
      - "./entrypoint.sh:/entrypoint.sh"
    environment:
      SLEEP_SECOND: 4
    tty: true
    entrypoint: /entrypoint.sh -d simonEureka:8100,simonConfig:8101 -c 'java -jar apigateway.jar';
  admin:
    image: simon/admin:2.0.1-SNAPSHOT
    ports:
      - "8103:8103"
    depends_on:
      - simonEureka
      - simonConfig
    volumes:
      - "./entrypoint.sh:/entrypoint.sh"
    environment:
      SLEEP_SECOND: 4
    tty: true
    entrypoint: /entrypoint.sh -d simonEureka:8100,simonConfig:8101 -c 'java -jar admin.jar';

启动服务

$ docker-compose up
[root@simon simon2.0]# docker-compose up
Starting simon20_simonEureka_1 ... done
Starting simon20_simonConfig_1 ... done
Starting simon20_admin_1       ... done
Starting simon20_apigateway_1  ... done
Attaching to simon20_simonEureka_1, simon20_simonConfig_1, simon20_admin_1, simon20_apigateway_1
simonConfig_1  | Waiting for simonEureka to listen on 8100...
simonConfig_1  | waiting...
admin_1        | Waiting for simonEureka to listen on 8100...
admin_1        | waiting...
apigateway_1   | Waiting for simonEureka to listen on 8100...
apigateway_1   | waiting...
......

其它服务都在等待simonEureka服务启动,这样就实现了服务的顺序启动,最终所有服务全部启动,如下是注册服务信息:

服务注册信息服务注册信息
上一篇下一篇

猜你喜欢

热点阅读