天天看點

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

摘要:對于一個合格的CloudNative應用,應該把自己的程式當做開源軟體來編寫的,不該将資料庫連接配接資訊和密碼放在代碼裡,一定要将配置外置。

對于一個合格的CloudNative應用,應該把自己的程式當做開源軟體來編寫的,不該将資料庫連接配接資訊和密碼放在代碼裡,一定要将配置外置。

是以我試着在華為雲上落地這套标準,期間嘗試了從ServiceStage、CCE、CSE這三個入口進行配置注入,最終實作能夠在應用啟動時,主動拉取配置,覆寫本地配置檔案裡的調試配置,并能夠線上配置并生效。

打法是:CCE配置啟動參數,制定SpringProfiles;配合CSE做應用配置,将資源外置後的配置記錄于此,并可以動态更新,最終實作了配置外置的訴求。

另外,通過這次增加的多版本管理,嘗試梳理了一下ServiceStage的元件、CCE的workload、CSE的應用和微服務之間,錯綜複雜的概念之間的關系,個人淺見,歡迎指正:

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

1. 初始化配置

在系統初始化的時候,不可能一點配置都沒有,是以保留一些基礎配置在配置檔案裡是有必要的。配置外置并不意味着100%的配置都要外置,而是把外部依賴資源的配置,特别是容易變化配置外置。

1.1 啟用Bootstrap和Spring profile

在代碼層面,首先要進行基礎配置。先看代碼結構,這裡除了最基本的application.yaml,增加了bootstrap.yaml和*-dev.yml等帶字尾的檔案。

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

介紹一下原理:

  • 首先介紹Bootstrap Application Context:

    它是Spring Cloud Context的父Context,是以從外部配置源裡加載配置一般從這裡來,且優先級高于其他一切配置檔案。于是,我們也利用這個能力,借助CSE的微服務配置中心能力,進行Spring的外部參數寫入。

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 然後介紹Spring profiles:

    為了把通用配置和環境相關的配置區分開,比如DEV環境沒有AK/SK認證,而線上環境都有認證,這種配置項上的差別,引入了Spring profiles的概念,當Springboot啟動的時候,會根據profiles.active參數判斷應該啟用那個環境配置

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

PS:參考SpringCloud官方解釋

另外,就是哪些配置應該放在配置檔案裡,理論上除了最基礎的配置,在啟動時使用的,其餘的配置都可以放在CSE的微服務配置中心裡,而不必在本地配置檔案裡存在,另外就是本地配置裡存在的,也可以通過二次設定在微服務的配置中心裡,進行覆寫,比如資料庫連接配接池的大小,而不需要修改代碼,至于改完以後,要不要重新開機,那就得看生效的邏輯了。

1.2 引入CSE配置中心

CSE配置中心引入,需要先引入依賴包,然後在bootstrap.yaml中配置CSE配置中心的位址、認證資訊等。

這裡可以參考官方文檔,主要關注bootstrap.yaml的配置參數:使用分布式配置中心

補充:擷取spring-cloud-starter-huawei-config的版本

參考位址:huaweicloud/spring-cloud-huawei

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

可以參考現有的SpringCloud基線版本,選擇SpringCloud-Huawei的版本

補充:關于配置中心的優先級

微服務引擎提供了分層次的配置機制。按照優先級從高到低,分為:

  • 配置中心(動态配置)
  • Java System Property(-D參數)
  • 環境變量
  • 配置檔案

參考官方文檔:配置微服務

2. 本地CSE配置中心能力驗證

前提條件,本地得安裝一個Local-CSE并啟動,這部分參考雲上DevOps:2.1-本地環境準備

2.1 配置application.yaml和bootstrap.yml

原始檔案可以參考Github的Demo,配置檔案入口,我這裡進行了修改,因為bootstrap.yaml優先級高于application.yaml,參數隻要在bootstrap.yaml中出現過,就不會使用application.yaml中的配置了。

上代碼,application.yaml,可以看到配置很少,因為大部分bootstrap.yml中已經包含,就都去掉了

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

這是bootstrap.yml,注意這裡的spring.application.name、spring.cloud.servicecomb.discovery.appName和spring.cloud.servicecomb.discovery.version會組成一個微服務私有的參數作用域,這裡的優先級高于全局作用域application。特别注意,雲上的CSE環境,除了上面提到的,還需要增加server.env參數。另外,server.env有四個參數可以選development、testing、acceptance、production

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

關于如上參數的定義,參考官方文檔:使用分布式注冊中心和官方文檔:使用分布式配置中心。

2.2 準備驗證代碼

直接上代碼

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

2.3 靜态配置能力

為了驗證CSE配置中心的參數,是否能覆寫application.yaml中的參數配置,我選了一個很特别的參數:spring.datasource.password,如果能夠覆寫成功,那麼啟動後,建立資料庫連接配接池一定會報錯。

  • 首先,打開本地CSE配置中心,位址為:http://localhost:30106/#/cse/services/config,建立一個配置項,作用域選VodMgrService@CabgOne#1.0.0,關于application的作用域後面再解釋。
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 重新開機本地微服務,啟動後建立資料庫連接配接池就報錯了,符合預期。
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

結論:CSE配置中心的參數,能夠覆寫application.yaml中的參數配置

2.4 動态配置能力

為了驗證CSE配置中心的參數動态生效,需要使用注解@RefreshScope,同時也引入ConfigRefreshEvent來監聽事件變化,這樣就會得到一個效果,對于動态生效的參數,可能需要一些重建或重新整理,比如連接配接池、緩存、Client等。

  • 首先,增加一個配置項config.value
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 然後很快可以看到背景日志列印出來,包括自己的監聽器,也響應了日志
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 檢視一下資料,已經響應為TryMe
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 具體的配置,在背景是輪詢的,響應周期配置參數為cloud.servicecomb.config.watch.delay,目前是10秒一次
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 修改一下配置,為TryMeAgain
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 再看背景日志,有新的觸發器發生
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 再次請求API,資料已經更新
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 再深入去看,這裡的getChange()傳回是一個Set<String>,是以可以針對特定的參數做文章。

結論:本地CSE配置中心的參數能夠動态重新整理,并開放了ConfigRefreshEvent,以擴充配置更新後的業務動作。

2.5 配置的作用域限制

目前CSE的配置中心提供兩級作用域限制,一個是全域,一個是私域,即微服務内部(不同版本有區分)。

  • 增加一個作用域為application的全域參數,一個作用域為VodMgrService@CabgOne#1.0.0的私域同名參數
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 驗證一下,生效的作用域是VodMgrService@CabgOne#1.0.0
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 删除私域參數後,生效的作用域是application
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

結論:本地CSE配置中心的全域配置的優先級,低于微服務内部配置,即私域配置可以覆寫全域配置。

3. 雲上配合外置落地

3.1 代碼送出并自動打包推送SWR

代碼送出,推送到CodeHub上,流水線在CloudPipeline自動驅動起來,開始執行,打包、制作鏡像、推送SWR,并且展開了代碼品質檢查。這些得益于前面的WIKI:Phase2 - 雲上DevOps

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

3.2 CCE啟動參數配置

由于ServiceStage的自動部署能力還不滿足,是以手工将DockerImage更新到環境上,這裡直接使用CCE進行操作,原因在題記裡介紹了,ServiceStage的參數配置不太好用

3.2.1 利用CCE的容器啟動指令寫入參數

  • 選擇更新版本,點進階配置,CCE的核心配置入口都在這裡了
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 在啟動時,注入最核心的一個參數-Dspring.profiles.active=uat
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 此處的指令是Docker啟動是的ENTRYPOINT,下面那個是CMD,會覆寫Dockerfile裡的指令
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 點選右下角的送出,會看到執行個體清單中已經有一個新的pod在啟動
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 回到AOM服務,檢視日志,會發現The following profiles are active: uat,符合預期
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

3.3 CCE環境變量配置

3.3.1 利用CCE的環境變量寫入參數

  • 首先回退上面那一步的配置,進入進階設定->環境變量
  • 增加環境變量JAVA_TOOL_OPTIONS,值設定為-Dspring.profiles.active=uat
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 送出以後檢視日志,符合預期
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

至于為啥JAVA_TOOL_OPTIONS能用,因為JVM原生就包含這個參數,可以用來在啟動時寫入配置,可以參考Oracle的官方文檔

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

3.4 CCE配置中心

3.4.1 利用CCE的配置中心 + 環境變量寫入參數

CCE的配置中心包含了兩個大類,配置項ConfigMap和秘鑰Secret,前面介紹的CCE環境變量,支援從配置中心導入參數,比如我可以在ConfigMap裡寫入這個參數,然後在CCE的環境變量中引入。

  • 首先建立一個配置項,這裡的配置項是按照叢集、命名空間區分的
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 然後建立一套配置項,輸入一套KV
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 回到CCE更新的步驟,修改環境變量,增加一項配置項寫入的變量,可以選到剛才輸入的KEY,就不用輸入VALUE了
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

然後再看看秘鑰,玩兒法類似,但是有一點很“有趣”:這裡的秘鑰是要主動用BASE64轉碼過才能儲存,不過在使用的時候,會解密的,是以不必關心轉碼回來的問題。

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

3.4.2 利用CCE的配置中心 + 資料存儲寫入參數

無論是配置項ConfigMap還是秘鑰Secret,都可以支援利用CCE的資料存儲挂載能力寫入參數到容器裡,簡單了解,就是會自動幫你把配置下載下傳到一個容器的存儲位置上,檔案名是KEY,内容是VALUE,可以在代碼裡讀取這個配置。

配置方式很簡單,選擇配置項,然後寫一個挂載目錄即可

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

3.5 雲上CSE配置中心

這裡是另一個核心,線下驗證過,雲上的CSE類似,但是配置模型更複雜,增加了server.env次元,并且全域和私域參數配置位置不一樣。

  • 首先,從ServiceStage->微服務CSE->配置管理,進入全域配置頁面,選擇環境為yaml裡配置的server.env參數

傳回結果為,生效

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

PS:如果這裡不選環境,則參數無法讀取,即環境為空也是一類環境,不同環境之間隔離

  • 然後,從ServiceStage->微服務CSE->微服務目錄,進入私域頁面
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

進而選擇動态配置,在配置作用域時,選擇不帶version的,環境是固定值,

一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置
  • 同樣的頁面下,在配置作用域時,選擇帶version的,
一個合格的CloudNative應用:程式當開源軟體編寫,應用配置外置

總結:雲上CSE配置中心參數加載優先級

  • P1:微服務私域,帶Version
  • P2:微服務私域,無Version
  • P3:全域,帶環境

    其餘參數都不生效,包括全域無環境、全域不同環境、微服務私域不同Version

總結

綜上,基于華為雲ServiceStage、CCE、CSE的配置外置能力,可以支撐微服務在不同環境中靈活部署,而無需修改代碼。目前的總結打法是:

  1. 利用CCE的容器啟動參數,或環境變量,寫入profiles.active參數
  2. 利用CSE的配置中心,寫入業務參數,如MySQL連接配接串、連接配接池配置、GES引擎位址、VOD服務Endpoint位址等

 本文分享自華為雲社群《[CloudNative] 企業應用上雲實踐手記-Cloud Native Phase 3 - 雲原生應用AutoConfig》,作者:關耳山石

點選關注,第一時間了解華為雲新鮮技術~

繼續閱讀