掌握SpringBoot-2.3的容器探針:深入篇

zq2599發表於2020-06-10

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

  • 內容:原創分類彙總及配套原始碼,涉及Java、Docker、K8S、DevOPS等

關於《SpringBoot-2.3容器化技術》系列

  • 《SpringBoot-2.3容器化技術》系列,旨在和大家一起學習實踐2.3版本帶來的最新容器化技術,讓我們們的Java應用更加適應容器化環境,在雲端計算時代依舊緊跟主流,保持競爭力;
  • 全系列文章分為主題和輔助兩部分,主題部分如下:
  1. 《體驗SpringBoot(2.3)應用製作Docker映象(官方方案)》
  2. 《詳解SpringBoot(2.3)應用製作Docker映象(官方方案)》
  3. 《掌握SpringBoot-2.3的容器探針:基礎篇》
  4. 《掌握SpringBoot-2.3的容器探針:深入篇》
  5. 《掌握SpringBoot-2.3的容器探針:實戰篇》
  • 輔助部分是一些參考資料和備忘總結,如下:
  1. 《SpringBoot-2.3映象方案為什麼要做多個layer》
  2. 《設定非root賬號不用sudo直接執行docker命令》
  3. 《開發階段,將SpringBoot應用快速部署到K8S》

前文回顧

  1. 本文是《掌握SpringBoot-2.3的容器探針》系列的第二篇,前文 《掌握SpringBoot-2.3的容器探針:基礎篇》知道了kubernetes的存活和就緒探針,以及SpringBoot-2.3的actuator新增的兩個endpoint,當我們把應用部署到kubernetes環境時,這些知識讓我們能配置出官方推薦的探針方案,如下圖:

在這裡插入圖片描述

  1. 儘管上述配置已經可以覆蓋多數場景,依然有三個問題未解決:
  • 首先,SpringBoot為kubernetes提供了兩個actuator項,但是那些並未部署在kubernetes的SringBoot應用呢?用不上這兩項也要對外暴露這兩個服務地址嗎?

  • 其次,就緒探針是什麼時候開始返回200返回碼的?應用啟動階段,業務服務可能需要一段時間才能正常工作,就緒探針要是提前返回了200,那k8s就認為容器可以正常工作了,這時候把外部請求排程過來是無法正常響應的,所以搞清楚就緒探針的狀態變化邏輯很重要;

  • 最後,也是最重要的一點:有的場景下,例如外部依賴服務異常、本地全域性異常等情況下,業務不想對外提供服務,等到問題解決後業務又可以對外提供服務了,如果此時我們能自己寫程式碼控制就緒探針的返回碼,那就做到了控制kubernetes是否將外部請求排程到此容器上,這可是個很實用的功能!

本篇就是為了解決上述問題而作,這些問題解決後才能用好探針技術,讓它在容器環境帶來更大價值;

關鍵知識點

解決上述問題的關鍵集中在以下幾個知識點:

  1. SpringBoot對容器環境的判斷;
  2. SpringBoot對狀態定義;
  3. 獲取狀態;
  4. 監聽狀態;
  5. 修改狀態;

接下來挨個學習這些知識點;

SpringBoot對容器環境的判斷

  1. 官方文件如下圖所示,SpringBoot判斷是否是kubernetes環境的邏輯很簡單:是否有_SERVICE_HOST_SERVICE_PORT這兩個環境變數:
    在這裡插入圖片描述

  2. 熟悉kubernetes的讀者看到_SERVICE_HOST"_SERVICE_PORT,應該會想起KUBERNETES_SERVICE_HOSTKUBERNETES_SERVICE_PORT,這是k8s給pod中配置的環境變數,看來SpringBoot也是針對k8s的這個規則來判定是否是容器環境的(如果將來k8s的某個版本不給pod設定這個環境變數,那些原本可以正常執行的pod豈不是有危險了?);

  3. 接下來通過實踐來驗證上述規則是否有效;

  4. 建立一個SpringBoot-2.3.0.RELEASE的應用,其pom.xml中的parent資訊如下:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.3.0.RELEASE</version>
  <relativePath/>
</parent>
  1. 增加actuator依賴:
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. 啟動該應用,瀏覽器訪問:http://localhost:8080/actuator/health/liveness,返回404錯誤:

在這裡插入圖片描述

  1. 以上返回是符合預期的,因為此時並非在kubernetes環境,接下來將"_SERVICE_HOST_SERVICE_PORT這兩個環境變數加入應用程式,看看是否有變化;
  2. 如下圖,編輯啟動類的配置資訊:

在這裡插入圖片描述

  1. 點選下圖紅框位置,即可進入編輯環境變數的視窗:

在這裡插入圖片描述

  1. 新的視窗中,操作如下圖紅框中所示,新增了兩個環境變數:

在這裡插入圖片描述

  1. 再次執行程式,這次返回的狀態碼是200:

在這裡插入圖片描述

  1. 至此,我們弄明白了SpringBoot是否開啟探針的邏輯,即應用是否執行在容器環境,而是否是容器環境的判定邏輯則是_SERVICE_HOST_SERVICE_PORT這兩個環境變數是否存在;

非kubernetes環境開啟探針

/actuator/health/liveness/actuator/health/readiness在kubernetes環境才會開啟,但是一般情況下,在開發階段SpringBoot應用可能執行在自己的電腦上,此時如果想檢視這兩個介面的返回值有兩種方式:

第一種,就是前面提到的新增_SERVICE_HOST_SERVICE_PORT這兩個環境變數,讓SpringBoot以為當前環境是kubernetes環境;

第二種,是按照官方指導新增屬性,如下圖紅框所示:

在這裡插入圖片描述

SpringBoot對探針相關狀態定義

  1. 首先要弄清楚有哪些狀態,原始碼是最準確的;
  2. 如下圖,存活探針一共有兩種狀態:CORRECT表示應用執行中並且內部狀態正常,BROKEN表示應用執行中並且內部是BROKEN狀態(請原諒我的英語水平)

在這裡插入圖片描述

  1. 如下圖,就緒探針一共有兩種狀態:ACCEPTING_TRAFFIC表示應用可以對外提供服務,REFUSING_TRAFFIC表示應用無法對外提供服務;

在這裡插入圖片描述

  1. 另外,上圖的since註解顯示這兩個列舉是從2.3.0版本開始生效的;

  2. 小小八卦一下,上述兩個列舉的作者Brian Clozel,座標法國里昂,目前在sringboot的提交次數排第8名:

在這裡插入圖片描述

  1. 在SpringBoot啟動過程中,應用、存活探針、就緒探針三者狀態對應關係如下圖:

在這裡插入圖片描述

  1. 在SpringBoot停止過程中,應用、存活探針、就緒探針三者狀態對應關係如下圖:

在這裡插入圖片描述

獲取狀態

如果業務應用想獲取當前的存活和就緒狀態,將ApplicationAvailability介面autowire進來即可,下一篇《實戰篇》會有詳細的使用方式,這裡看下關鍵程式碼:

在這裡插入圖片描述

監聽狀態

得益於Spring完整的事件釋出和訂閱機制,業務應用通過EventListener註解就能監聽到存活和就緒狀態的變化,在EventListener註解修飾的方法中寫入必要的業務程式碼即可實現狀態監聽,下一篇《實戰篇》會有詳細的使用方式,這裡看下關鍵程式碼:

在這裡插入圖片描述

修改狀態

  1. 修改狀態,尤其是就緒狀態,這應該是我們最關注的功能了,在某些業務場景下,應用無法對外提供服務,這時候我們希望K8S不要將外部請求排程到這裡,如果K8S通過就緒探針收到返回碼非200,就不再將請求排程到這個pod上;
  2. 下一篇《實戰篇》會有詳細的程式碼介紹,這裡給出關鍵程式碼作為參考:

在這裡插入圖片描述

請注意

重要的事情一定要強調:我們們修改狀態的最終目的,不是為了取得applicationAvailability.getReadinessState()返回新的列舉物件,而是要改變/actuator/health/readiness介面的返回碼(就緒是200,未就緒是503),這是kubernetes的探針規則要用到的;

為啥都放在下一篇

  1. 文章看到這裡您可能已經火冒三丈了:關鍵程式碼都貼出來了,為啥不在本章給出完整原始碼?騙點選量?湊字數?湊文章數?
  2. 存活和就緒探針是在kubernetes環境下的工具,為了給您提供儘量準確和完整的參考,所有的程式碼和操作都必須在kubernetes環境完成除錯才能釋出,而且這些操作應該作為單獨章節,與當前的理論知識分開;
  3. 歡迎進入《實戰篇》,隨SpringBoot-2.3.0.RELEASE,一起在kubernetes世界暢遊;

歡迎關注我的公眾號:程式設計師欣宸

在這裡插入圖片描述

https://github.com/zq2599/blog_demos

相關文章