Docker-compose编排微服务顺序启动

发布时间:2020-04-23 09:34:05编辑:admin阅读(211)

    一、概述

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

     

    微服务清单

    服务名端口服务说明依赖服务启动优先级
    eureka-service8761服务注册与发现---1
    auth-service8888认证服务eureka-service2
    user-service8763用户服务eureka-service2
    gateway-service8081网关服务eureka-service2

     

     

     

     




     

     

    说明:eureka需要第一个启动,其他微服务必须等待eureka启动之后,才能启动。否则无法注册服务!

     

    二、解决方案

    针对这个问题,docker-compose官方给的建议是,通过wait-for-it.sh脚本来控制。

    简单来说,这个脚本就是探测某个依赖的服务的tcp端口是否开放,否则一直等待,直到端口探测成功,才会启动后面的命令。

    关于wait-for-it.sh的使用,请参考链接:

    https://blog.csdn.net/wuzhong8809/article/details/82500722

     

    环境说明

    本文采用一台centos 7.6,通过docker-compose启动java spring cloud

    ip地址:192.168.128.130

     

    但是我测试了一下,使用wait-for-it.sh探测eureka的8761端口。发现虽然端口探测成功了,但是并不代表eureka完全启动好了。因此此时无法访问eureka的页面!

    那么如何判断eureka完全启动好了呢?很简单,只需要访问eureka页面,http状态码为200,就表示启动好了。

    curl -I -m 10 -o /dev/null -s -w %{http_code}  http://eureka-server:8761

     

    那么问题来了,还是得需要自己写检查脚本才行。

    check_eureka.sh

    #!/bin/bash
    
    while :
        do
            # 访问eureka注册中心,获取http状态码
            CODE=`curl -I -m 10 -o /dev/null -s -w %{http_code}  http://kitedge-eureka-server:8761`
            # 判断状态码为200
            if [[ $CODE -eq 200 ]]; then
                # 输出绿色文字,并跳出循环
                echo -e "\033[42;34m kitedge-eureka-server is ok \033[0m"
                break
            else
                # 暂停1秒
                sleep 1
            fi
        done
    
    # while结束时,也就是eureka启动完成后,执行容器中的run.sh。
    bash /run.sh

    说明:访问eureka注册中心,获取http状态码。当为200时,跳出循环,执行其他容器中的run.sh。

    否则就一直循环,直到eureka页面正常为止。

     

    目录结构

    /opt/springcloud 目录结构如下:

    ./
    ├── auth
    │   ├── auth-server.jar
    │   ├── dockerfile
    │   ├── repositories
    │   └── run.sh
    ├── check_eureka.sh
    ├── docker-compose.yml
    ├── eureka
    │   ├── dockerfile
    │   ├── eureka-server.jar
    │   ├── repositories
    │   └── run.sh
    ├── gateway
    │   ├── dockerfile
    │   ├── gateway-server.jar
    │   ├── repositories
    │   └── run.sh
    └── user
        ├── dockerfile
        ├── repositories
        ├── run.sh
        └── user-service.jar

    这里有4个微服务

     

    docker-compose.yml

    version: '3'
    services:
      eureka-server:
        image: eureka-server:1
        container_name: eureka-server
        build: ./eureka
        volumes:
          - ./check_eureka.sh:/check_eureka.sh
          - /data/log/tomcat:/data/log/tomcat
          - /data/file:/data/file
        environment:
          - JVM=128m
        ports:
          - "8761:8761"
        networks:
          test_net:
            aliases:
              - eureka-server
        restart: always
        command: ["bash","/check_eureka.sh"]
        healthcheck:
          test: "/bin/netstat -anpt|grep 8761"
          interval: 30s
          timeout: 3s
          retries: 1
    
      auth-server:
        image: auth-server:1
        container_name: auth-server
        build: ./auth
        volumes:
          - ./check_eureka.sh:/check_eureka.sh
          - /data/log/tomcat:/data/log/tomcat
          - /data/file:/data/file
        environment:
          - JVM=128m
        ports:
          - "8888:8888"
        networks:
          test_net:
            aliases:
              - auth-server
        restart: always
        depends_on:
          - "eureka-server"
        command: ["bash","/check_eureka.sh"]
        healthcheck:
          test: "/bin/netstat -anpt|grep 8888"
          interval: 30s
          timeout: 3s
          retries: 1
    
      user-service:
        image: user-service:1
        container_name: user-service
        build: ./user
        volumes:
          - ./check_eureka.sh:/check_eureka.sh
          - /data/log/tomcat:/data/log/tomcat
          - /data/file:/data/file
        environment:
          - JVM=128m
        ports:
          - "8763:8763"
        networks:
          test_net:
            aliases:
              - user-service
        restart: always
        depends_on:
          - "eureka-server"
        command: ["bash","/check_eureka.sh"]
        healthcheck:
          test: "/bin/netstat -anpt|grep 8763"
          interval: 30s
          timeout: 3s
          retries: 1
    
      gateway-server:
        image: gateway-server:1
        container_name: gateway-server
        build: ./gateway
        volumes:
          - ./check_eureka.sh:/check_eureka.sh
          - /data/log/tomcat:/data/log/tomcat
          - /data/file:/data/file
        environment:
          - JVM=128m
        ports:
          - "8081:8081"
        networks:
          test_net:
            aliases:
              - gateway-server
        restart: always
        depends_on:
          - "eureka-server"
        command: ["bash","/check_eureka.sh"]
        healthcheck:
          test: "/bin/netstat -anpt|grep 8081"
          interval: 30s
          timeout: 3s
          retries: 1
    
    networks:
        test_net:
          external: true

    参数解释:

    image:指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取镜像。

    container_name:容器名称,相当于docker run --name xxx,里面的--name参数。

    build:指定Dockerfile所在文件夹的路径。Compose将会利用Dockerfile自动构建镜像,然后使用镜像启动服务容器。

    volumes:挂载一个目录或者一个已存在的数据卷容器,相当于docker run -v xxx:xxx里面的-v参数。

    environment:环境变量,相当于docker run -e xxx=xxx里面的-e参数。

    ports:映射端口,相当于docker run -p xx:xx里面的-p参数。

    networks:网络设置,这里表示连接test_net网桥,aliases表示设置别名。相当于docker run -it --network xx --network-alias xxx

    restart:重启方式,相当于docker run --restart里面的--restart参数。

    depends_on:指定依赖于哪个服务

    command:覆盖容器启动后默认执行的命令,相当于docker run xxx /bin/bash里面最后一段命令。

    healthcheck: 判断容器的状态是否正常
    设置选项:

    • test:测试命令

    • --interval=DURATION (default: 30s),间隔

    • --timeout=DURATION (default: 30s), 超时时间

    • --start-period=DURATION (default: 0s),初始化时间

    • --retries=N (default: 3),当连续失败指定次数后,容器状态会变成unhealthy

     

     这里主要介绍eureka目录下的几个文件。

    dockerfile

    FROM mayan31370/openjdk-alpine-with-chinese-timezone:8-jdk
    ADD eureka-server.jar /
    ADD run.sh /
    RUN chmod 755 run.sh && mkdir -p /data/log/tomcat /data/file
    
    EXPOSE 8761
    ENTRYPOINT [ "/run.sh"]


    repositories

    #https://mirrors.aliyun.com/alpine/v3.6/main/
    #https://mirrors.aliyun.com/alpine/v3.6/community/
    #aliyun
    https://mirrors.aliyun.com/alpine/v3.6/main/
    https://mirrors.aliyun.com/alpine/v3.6/community/

    run.sh

    #!/bin/sh
    
    java -Xms${JVM} -Xmx${JVM} -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=256m -jar /eureka-server.jar

    再来看auth下的几个文件。

    dockerfile

    FROM mayan31370/openjdk-alpine-with-chinese-timezone:8-jdk
    ADD auth-server.jar /
    ADD repositories /etc/apk/repositories
    ADD run.sh /
    RUN chmod 755 run.sh && mkdir -p /data/log/tomcat /data/file && apk update && apk add bash curl
    
    EXPOSE 8888
    #ENTRYPOINT [ "/run.sh"]

    注意:这里注释掉了ENTRYPOINT ,因为它由check_eureka.sh脚本来启动。注意看此脚本的最后一行,它就是来执行run.sh的。

     

    repositories

    内容同上,这里就不重复贴了

     

    run.sh

    #!/bin/sh
    
    java -Xms${JVM} -Xmx${JVM} -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=256m -jar /auth-server.jar

    另外2个微服务,user和gateway。和auth也是类似的,只不过dockerfile和run.sh里面的jar包名不一样,其他内容都是一样的。

     

    启动服务

    创建bridge网络

    docker network create test_net

    一切准备就绪了,先build,再启动。

    cd /opt/springcloud
    docker-compose build
    docker-compose up -d

    等待几分钟,查看容器状态

    # docker-compose ps
         Name                   Command                 State               Ports         
    --------------------------------------------------------------------------------------
    auth-server      bash /check_eureka.sh           Up (healthy)   0.0.0.0:8888->8888/tcp
    eureka-server    /run.sh bash /check_eureka.sh   Up (healthy)   0.0.0.0:8761->8761/tcp
    gateway-server   bash /check_eureka.sh           Up (healthy)   0.0.0.0:8081->8081/tcp
    user-service     bash /check_eureka.sh           Up (healthy)   0.0.0.0:8763->8763/tcp

     

    访问eureka注册中心

    http://192.168.128.130:8761/

     

    效果如下:

    1.png

     

     

     

     

    本文参考连接:

    https://blog.csdn.net/wuzhong8809/article/details/82500722

    https://www.jianshu.com/p/d2f39703bcb5


关键字