Docker-compose編排微服務順序啟動
一、概述
docker-compose可以方便組合多個 docker 容器服務, 但是, 當容器服務之間存在依賴關系時, docker-compose 並不能保證服務的啟動順序。docker-compose 中的 depends_on 配置是容器的啟動順序, 並不是容器中服務的啟動順序。本章將詳細敘述如何解決 docker-compose 順序啟動微服務的問題。
微服務清單
服務名 |
端口 |
服務說明 |
依賴服務 |
啟動優先級 |
---|---|---|---|---|
eureka-service |
8761 |
服務注冊與發現 |
--- |
1 |
auth-service |
8888 |
認證服務 |
eureka-service |
2 |
user-service |
8763 |
用戶服務 |
eureka-service |
2 |
gateway-service |
8081 |
網關服務 |
eureka-service |
2 |
說明: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