1. 程式人生 > >掌握SpringBoot-2.3的容器探針:深入篇

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

### 歡迎訪問我的GitHub [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) - 內容:原創分類彙總及配套原始碼,涉及Java、Docker、K8S、DevOPS等 ### 關於《SpringBoot-2.3容器化技術》系列 - 《SpringBoot-2.3容器化技術》系列,旨在和大家一起學習實踐2.3版本帶來的最新容器化技術,讓咱們的Java應用更加適應容器化環境,在雲端計算時代依舊緊跟主流,保持競爭力; - 全系列文章分為主題和輔助兩部分,主題部分如下: 1. [《體驗SpringBoot(2.3)應用製作Docker映象(官方方案)》](https://blog.csdn.net/boling_cavalry/article/details/106597358); 2. [《詳解SpringBoot(2.3)應用製作Docker映象(官方方案)》](https://blog.csdn.net/boling_cavalry/article/details/106598189); 3. [《掌握SpringBoot-2.3的容器探針:基礎篇》](https://blog.csdn.net/boling_cavalry/article/details/106605264); 4. [《掌握SpringBoot-2.3的容器探針:深入篇》](https://blog.csdn.net/boling_cavalry/article/details/106606442); 5. [《掌握SpringBoot-2.3的容器探針:實戰篇》](https://blog.csdn.net/boling_cavalry/article/details/106607225); - 輔助部分是一些參考資料和備忘總結,如下: 1. [《SpringBoot-2.3映象方案為什麼要做多個layer》](https://blog.csdn.net/boling_cavalry/article/details/106600620); 2. [《設定非root賬號不用sudo直接執行docker命令》](https://blog.csdn.net/boling_cavalry/article/details/106590784); 3. [《開發階段,將SpringBoot應用快速部署到K8S》](https://blog.csdn.net/boling_cavalry/article/details/106594392); ### 前文回顧 1. 本文是《掌握SpringBoot-2.3的容器探針》系列的第二篇,前文 [《掌握SpringBoot-2.3的容器探針:基礎篇》](https://blog.csdn.net/boling_cavalry/article/details/106605264)知道了kubernetes的存活和就緒探針,以及SpringBoot-2.3的actuator新增的兩個endpoint,當我們把應用部署到kubernetes環境時,這些知識讓我們能配置出官方推薦的探針方案,如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074506693-1682499065.png) 2. 儘管上述配置已經可以覆蓋多數場景,依然有三個問題未解決: - 首先,SpringBoot為kubernetes提供了兩個actuator項,但是那些並未部署在kubernetes的SringBoot應用呢?用不上這兩項也要對外暴露這兩個服務地址嗎? - 其次,就緒探針是什麼時候開始返回200返回碼的?應用啟動階段,業務服務可能需要一段時間才能正常工作,就緒探針要是提前返回了200,那k8s就認為容器可以正常工作了,這時候把外部請求排程過來是無法正常響應的,所以搞清楚就緒探針的狀態變化邏輯很重要; - 最後,也是最重要的一點:有的場景下,例如外部依賴服務異常、本地全域性異常等情況下,業務不想對外提供服務,等到問題解決後業務又可以對外提供服務了,如果此時我們能自己寫程式碼控制就緒探針的返回碼,那就做到了控制kubernetes是否將外部請求排程到此容器上,這可是個很實用的功能! 本篇就是為了解決上述問題而作,這些問題解決後才能用好探針技術,讓它在容器環境帶來更大價值; ### 關鍵知識點 解決上述問題的關鍵集中在以下幾個知識點: 1. SpringBoot對容器環境的判斷; 2. SpringBoot對狀態定義; 3. 獲取狀態; 4. 監聽狀態; 5. 修改狀態; 接下來挨個學習這些知識點; ### SpringBoot對容器環境的判斷 1. 官方文件如下圖所示,SpringBoot判斷是否是kubernetes環境的邏輯很簡單:是否有*_SERVICE_HOST和*_SERVICE_PORT這兩個環境變數: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074506943-68039617.png) 2. 熟悉kubernetes的讀者看到*_SERVICE_HOST" 和*_SERVICE_PORT,應該會想起KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT,這是k8s給pod中配置的環境變數,看來SpringBoot也是針對k8s的這個規則來判定是否是容器環境的(如果將來k8s的某個版本不給pod設定這個環境變數,那些原本可以正常執行的pod豈不是有危險了?); 3. 接下來通過實踐來驗證上述規則是否有效; 4. 建立一個SpringBoot-2.3.0.RELEASE的應用,其pom.xml中的parent資訊如下: ```xml ``` 5. 增加actuator依賴: ```xml ``` 6. 啟動該應用,瀏覽器訪問:http://localhost:8080/actuator/health/liveness,返回404錯誤: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074507239-1345076910.png) 7. 以上返回是符合預期的,因為此時並非在kubernetes環境,接下來將"*_SERVICE_HOST 和*_SERVICE_PORT這兩個環境變數加入應用程序,看看是否有變化; 8. 如下圖,編輯啟動類的配置資訊: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074507567-452988648.png) 9. 點選下圖紅框位置,即可進入編輯環境變數的視窗: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074507913-1861514923.png) 10. 新的視窗中,操作如下圖紅框中所示,新增了兩個環境變數: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074508377-1348688480.png) 11. 再次執行程式,這次返回的狀態碼是200: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074508687-1464269414.png) 12. 至此,我們弄明白了SpringBoot是否開啟探針的邏輯,即應用是否執行在容器環境,而是否是容器環境的判定邏輯則是*_SERVICE_HOST和*_SERVICE_PORT這兩個環境變數是否存在; ### 非kubernetes環境開啟探針 /actuator/health/liveness和/actuator/health/readiness在kubernetes環境才會開啟,但是一般情況下,在開發階段SpringBoot應用可能執行在自己的電腦上,此時如果想檢視這兩個介面的返回值有兩種方式: 第一種,就是前面提到的新增*_SERVICE_HOST和*_SERVICE_PORT這兩個環境變數,讓SpringBoot以為當前環境是kubernetes環境; 第二種,是按照官方指導新增屬性,如下圖紅框所示: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074508987-1336819275.png) ### SpringBoot對探針相關狀態定義 1. 首先要弄清楚有哪些狀態,原始碼是最準確的; 2. 如下圖,存活探針一共有兩種狀態:CORRECT表示應用執行中並且內部狀態正常,BROKEN表示應用執行中並且內部是BROKEN狀態(請原諒我的英語水平) ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074509281-1533585551.png) 3. 如下圖,就緒探針一共有兩種狀態:ACCEPTING_TRAFFIC表示應用可以對外提供服務,REFUSING_TRAFFIC表示應用無法對外提供服務; ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074509502-628665374.png) 4. 另外,上圖的since註解顯示這兩個列舉是從2.3.0版本開始生效的; 5. 小小八卦一下,上述兩個列舉的作者Brian Clozel,座標法國里昂,目前在sringboot的提交次數排第8名: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074509703-15700355.png) 6. 在SpringBoot啟動過程中,應用、存活探針、就緒探針三者狀態對應關係如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074509979-2013709261.png) 7. 在SpringBoot停止過程中,應用、存活探針、就緒探針三者狀態對應關係如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074510346-1894757529.png) ### 獲取狀態 如果業務應用想獲取當前的存活和就緒狀態,將ApplicationAvailability介面autowire進來即可,下一篇[《實戰篇》](https://blog.csdn.net/boling_cavalry/article/details/106607225)會有詳細的使用方式,這裡看下關鍵程式碼: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074510653-1669256498.png) ### 監聽狀態 得益於Spring完整的事件釋出和訂閱機制,業務應用通過EventListener註解就能監聽到存活和就緒狀態的變化,在EventListener註解修飾的方法中寫入必要的業務程式碼即可實現狀態監聽,下一篇[《實戰篇》](https://blog.csdn.net/boling_cavalry/article/details/106607225)會有詳細的使用方式,這裡看下關鍵程式碼: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074510865-211293395.png) ### 修改狀態 1. 修改狀態,尤其是就緒狀態,這應該是我們最關注的功能了,在某些業務場景下,應用無法對外提供服務,這時候我們希望K8S不要將外部請求排程到這裡,如果K8S通過就緒探針收到返回碼非200,就不再將請求排程到這個pod上; 2. 下一篇[《實戰篇》](https://blog.csdn.net/boling_cavalry/article/details/106607225)會有詳細的程式碼介紹,這裡給出關鍵程式碼作為參考: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074511113-1877140164.png) ### 請注意 重要的事情一定要強調:咱們修改狀態的最終目的,不是為了取得applicationAvailability.getReadinessState()返回新的列舉物件,而是要改變/actuator/health/readiness介面的返回碼(就緒是200,未就緒是503),這是kubernetes的探針規則要用到的; ### 為啥都放在下一篇 1. 文章看到這裡您可能已經火冒三丈了:關鍵程式碼都貼出來了,為啥不在本章給出完整原始碼?騙點選量?湊字數?湊文章數? 2. 存活和就緒探針是在kubernetes環境下的工具,為了給您提供儘量準確和完整的參考,所有的程式碼和操作都必須在kubernetes環境完成除錯才能釋出,而且這些操作應該作為單獨章節,與當前的理論知識分開; 3. 歡迎進入[《實戰篇》](https://blog.csdn.net/boling_cavalry/article/details/106607225),隨SpringBoot-2.3.0.RELEASE,一起在kubernetes世界暢遊; ### 歡迎關注我的公眾號:程式設計師欣宸 ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202006/485422-20200610074511383-952103949.jpg) [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blo