一、概述
微服務清單
服務名 | 端口 | 服務說明 | 依賴服務 | 啟動優先級 |
eureka-service | 8761 | 服務注冊與發現 | --- | 1 |
auth-service | 8888 | 認證服務 | eureka-service | 2 |
user-service | 8763 | 用戶服務 | eureka-service | 2 |
gateway-service | 8081 | 網關服務 | eureka-service | 2 |
二、解決方案
針對這個問題,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

本文參考連接: