docker-compose下的java應用啟動順序兩部曲之一:問題分析

来源:https://www.cnblogs.com/bolingcavalry/archive/2019/11/02/11784526.html
-Advertisement-
Play Games

在docker compose編排多個容器時,需要按實際情況控制各容器的啟動順序,本文是《docker compose下的java應用啟動順序兩部曲》的第一篇,文中會分析啟動順序的重要性,以及啟動順序有問題時會有什麼樣的影響,再給出臨時解決的和官方推薦的兩種解決方案,為下一篇的實戰做好鋪墊。 環境信 ...


在docker-compose編排多個容器時,需要按實際情況控制各容器的啟動順序,本文是《docker-compose下的java應用啟動順序兩部曲》的第一篇,文中會分析啟動順序的重要性,以及啟動順序有問題時會有什麼樣的影響,再給出臨時解決的和官方推薦的兩種解決方案,為下一篇的實戰做好鋪墊。

環境信息

本次實戰的環境如下:

  1. 操作系統:CentOS Linux release 7.7.1908
  2. docker:1.13.1
  3. docker-compose:1.24.1
  4. spring cloud:Finchley.RELEASE

    分散式環境中的依賴關係

    在分散式環境中,各服務之間可能存在依賴關係,例如SpringCloud環境中的應用在啟動時都會先往註冊中心Eurka發起請求,如下圖(來自spring官方博客:https://spring.io/blog/2015/07/14/microservices-with-spring ):
    在這裡插入圖片描述
    從上圖可知,如果Eureka的服務不可用,就會影響業務服務的功能;

Docker環境中的依賴關係

  1. 上述服務如果用docker-compose編排在一起,也面依賴著問題:Eureka容器啟動完畢並且能提供http服務以後,業務服務的容器才能在Eureka註冊成功並取得服務列表,通常我們都使用depends_on參數來設定依賴關係;
  2. 以下是個docker-compose.yml文件,裡面有兩個容器:eureka和service,eureka是註冊中心,service是業務服務,service啟動後要去eureka註冊,為了確保啟動順序,service配置了depends_on參數:
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 'java -Xms1g -Xmx1g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.waitforitdemo.ServiceApplication'
    depends_on:
    - eureka
  1. 上述yml文件能解決依賴問題嗎?service服務啟動時能否成功在eureka註冊?來試試吧,在Linux電腦上創建docker-compose.yml文件,內容如上所示;
  2. 在docker-compose.yml所在目錄執行docker-compose up,docker服務會先去hub.docker.com下載鏡像,然後依次創建容器,控制台會同時列印eureka和service的日誌,如下圖所示,service註冊eureka失敗了,請註意圖中的文字分析:
    在這裡插入圖片描述
  3. 為何會註冊失敗呢?繼續看後面的日誌,如下圖,service註冊失敗後eureka才初始化完成,所以前面的service註冊會失敗:
    在這裡插入圖片描述
  4. 至此可以確定:depends_on參數可以確保eureka容器啟動後再啟動service容器,但我們真正想要的,是eureka容器啟動後,並且eureka服務初始化完畢進入可用狀態後,再啟動service容器,顯然depends_on參數達不到我們的要求;
  5. docker官方文檔也證實了這一點,如下圖紅框所示:
    在這裡插入圖片描述
  6. 看來depends_on參數解決不了我們的問題,需要去尋找其他方法;

另外您可能會說:沒關係,service會自動重新註冊,但是在真實環境中,不是每個服務都有能力去自己解決依賴不可用的問題,例如spring-cloud-config服務如果起不來,依賴它的服務可能會立即停止;

有一種臨時方法(此方法V3版語法不再支持)

  1. 如果eureka容器配置了健康檢查,那麼service容器可以配置健康檢查依賴來控制啟動時機,具體的做法可以參考官方示例,如下所示,地址是:https://docs.docker.com/compose/compose-file/compose-file-v2/
version: "2.4"
services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  redis:
    image: redis
  db:
    image: redis
    healthcheck:
      test: "exit 0"

從上述編排內容可見:db容器有健康檢查,可以確定db容器的服務是否可用,web容器的depends_on參數內可以配置condition,這樣就做到了只有redis已經啟動並且db的健康檢查通過,才會啟動web容器;

  1. 上述配置看起來似乎是個不錯的方案,在我們這裡,只要給eureka配置要健康檢查,再讓service容器的depends_on參數內配置condition: service_healthy就可以了;
  2. 不幸的是:在docker-compose的第三版語法中,取消了condition參數!文檔地址是:https://docs.docker.com/compose/compose-file/ ,如下圖紅框所示:
    在這裡插入圖片描述
  3. 因此,condition參數看似好用,但是從V3版開始的docker-compose.yml已經不再支持該參數,不能作為標準的解決方案;

官方推薦的方案

如下圖紅框所示,docker官方推薦使用wait-for-it.sh腳本來解決問題,地址:https://docs.docker.com/compose/startup-order/
在這裡插入圖片描述
至此,本篇已經分析了docker-compose下容器啟動順序的問題,下一篇文章,我們用SpringCloud應用來做實戰,將其做到在docker-compose下有序啟動;

參考文章

如果您對docker容器健康檢查有興趣,可以參考以下文章:

  1. 《極速體驗docker容器健康》
  2. 《Java應用在docker環境配置容器健康檢查》

    歡迎關註公眾號:程式員欣宸


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 #需求 遍歷文件夾中所有的子文件夾及子文件--用遞歸實現 2 3 '''''' 4 ''' 5 偽代碼 6 1、遍歷根目錄--listdir for 7 得到第一級子文件夾(不包含子文件夾的子文件)和文件 8 2、判斷是文件還是文件夾 9 如果是文件,就直接列印文件名 10 如果是文件夾(全路徑... ...
  • 2019-11-02-23:25:26 目錄 1.泛型的概念: 2.泛型的定義和使用: 2.1定義和使用含有泛型的類: 2.2定義和使用含有泛型的方法: 2.3定義和使用含有泛型的介面: 泛型的概念: 泛型是一種未知的數據類型,當我門不知道使用什麼數據類型的時候,可以使用泛型,泛型也可以看成是一個變 ...
  • 1、表達式:關係表達式或邏輯表達式; 2、表達式的運算結果應該是“真”或者“假”; 真:執行該語句; 假:跳過該語句,執行下一條語句; 3、“語句”可以是單語句也可以是複合語句; 4、else if 可以有多條,沒有上限; 5、if 和 else if都需要判斷表達式真假,else則不需要,else ...
  • 操作系統 : CentOS7.3.1611_x64 Python 版本 : 3.6.8 tornado版本:6.0.2 snaic版本:19.9.0 CPU : Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz 4核 之前一直使用tornado作為http相關pytho ...
  • 1. Spring Spring框架是一個輕量級的解決方案,是一個潛在的一站式商店,用於構建企業就緒的應用程式。Spring框架是一個Java平臺,為開發Java應用程式提供全面的基礎架構支持。Spring處理基礎結構,因此您可以專註於應用程式。Spring使您能夠從“普通的Java對象”(POJO ...
  • Eureka是Netflix開發的服務發現框架,本身是一個基於REST的服務,主要用於定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。 SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務發現功能。 ... ...
  • 本篇文章給大家帶來的內容是關於Laravel API跨域訪問的實現步驟,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。 伺服器A請求伺服器B的介面,那麼一般會出現跨域問題。 1 XMLHttpRequest cannot load http://api.console.vms3.co ...
  • 用一個裝飾器,監控程式的運行時間 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...