SpringBoot(19)---SpringBoot整合Apollo

雨點的名字發表於2020-08-25

SpringBoot(19)---SpringBoot整合Apollo

有關Apollo之前已經寫了兩篇文章:

1、【Apollo】(1)--- Apollo入門介紹篇

2、【Apollo】(2)--- Apollo架構設計

這篇文章分為兩部分:

1、跟著官網步驟,快速搭建apollo環境

2、SpringBoot整合apollo,實現配置中心

一、Apollo快速搭建

apollo環境的搭建主要參考 官方文件 ,我們就直接一步一步跟著官方文件來

1、下載Quick Start安裝包

下載apollo-build-scripts專案

2、建立資料庫

之前有說過,apollo會有兩個資料庫: ApolloPortalDBApolloConfigDB

建立ApolloPortalDB

建立ApolloConfigDB

3、更新資料庫連線資訊

在下載下來的Quick Start專案中,有個叫demo.sh的檔案,我們需要 修改資料庫連線資訊,修改裡頭資料庫連線地址/使用者名稱/密碼

4、 啟動Apollo配置中心

上面三部就已經將環境搭建好,現在我們開始啟動Apollo配置中心,來看具體效果。

注意 這裡預設暫用三個埠: 8070,8080,8090,所以要先看下這三個埠有木有被暫用。

啟動專案

./demo.sh start

5、登入Apollo

網址:http://localhost:8070/

登入介面

SpringBoot(19)---SpringBoot整合Apollo

初始賬號密碼 : apollo/admin

進入首頁之後,我們可以看到: 預設的環境只有dev,m預設有一個SampleApp專案

SpringBoot(19)---SpringBoot整合Apollo

我們在這裡新增兩個配置

6. 測試客戶程式碼

上面已經設定了兩個配置,這個時候我們就需要通過客戶端去獲取,我們先不通過SpringBoot去獲取,而是官方提供的客戶端去獲取配置

執行客戶端

./demo.sh client

啟動後去查詢配置

SpringBoot(19)---SpringBoot整合Apollo

可以看到客戶端都能夠拿到配置中心的配置。

注意 這裡有一點在上面我設了 gougou:4歲。而實際客戶端獲得的是4?,所以中文沒有轉義成功,在實際開發中,我們也儘量去避免有中文漢字來當配置。

這樣下來,官方給的快速啟動apollo是成功了,下面我們把客戶端換成SpringBoot,來實現獲取配置中心的資料。


二、SpringBoot整合Apollo

從上面我們可以知道在apollo官方給了我們一個預設專案叫:SampleApp。預設的使用者名稱稱:apollo。所以這裡靈活一點,不用它自己的,而是我們手動新增。

1、Apollo建立新新使用者和專案

1)新增新使用者

http://{portal地址}/user-manage.html  //我們這裡設定的是http://localhost:8070/user-manage.html
SpringBoot(19)---SpringBoot整合Apollo

這裡新增一個使用者名稱叫:liubei

2)新增專案

訪問http://localhost:8070 登入後,選擇建立專案。

SpringBoot(19)---SpringBoot整合Apollo

這裡新建立了專案,一個AppId名稱叫: springboot-test-apollo

配置說明

部門:選擇應用所在的部門。(想自定義部門,參照官方文件,這裡就選擇樣例)

應用AppId:用來標識應用身份的唯一id,格式為string,需要和客戶端。application.properties中配置的app.id對應。

應用名稱:應用名,僅用於介面展示。

應用負責人:選擇的人預設會成為該專案的管理員,具備專案許可權管理、叢集建立、Namespace建立等許可權。

提交配置後會出現如下專案配置的管理頁面。

3)新增配置

SpringBoot(19)---SpringBoot整合Apollo

這裡先新增一個新配置: date.value = 2020.08.04

2、springboot專案搭建

上面把apollo環境搭建好,也建立了新專案,那麼這裡就去讀取新專案的配置資訊。

1)pom.xml

新增 Apollo 客戶端的依賴,其它依賴這裡就不展示了,完整專案會放在github上。

<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-client</artifactId>
    <version>1.3.0</version>
</dependency>

2)application.yml

server:
  port: 8123

app:
  id: springboot-test-apollo
apollo:
  meta: http://127.0.0.1:8080
  bootstrap:
    enabled: true
    eagerLoad:
      enabled: true

#這裡說明在將該專案 com目錄下的日誌,都採用info模式輸出
logging:
  level:
    com: info

配置說明

app.id :AppId是應用的身份資訊,是配置中心獲取配置的一個重要資訊。

apollo.bootstrap.enabled:在應用啟動階段,向Spring容器注入被託管的application.properties檔案的配置資訊。

apollo.bootstrap.eagerLoad.enabled:將Apollo配置載入提到初始化日誌系統之前。

logging.level.com :調整 com 包的 log 級別,為了後面演示在配置中心動態配置日誌級別。

3) TestController

@Slf4j
@RestController
public class TestController {

    @Value( "${date.value}" )
    String dateValue;

    @GetMapping("test")
    public String test() {
        return "列印配置中心的 dateValue 值: "+ dateValue;
    }

}

4)SpringBoot啟動類

@SpringBootApplication
@EnableApolloConfig
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

新增 EnableApolloConfig 配置註解

3、測試

我在apollo配置了一個屬性: date.value = 2020.08.04,如果從springBoot能夠獲取到該配置,那麼就說明成功了。

SpringBoot(19)---SpringBoot整合Apollo

很明顯,我們通過介面已經成功獲取配置中心的配置。這樣一個最簡單的整合已經完成了,下面我們在來驗證其它東西。


三、驗證

下面我們來驗證一些有意思的東西:

1)、配置修改後能否立即生效

2)、通過配置日誌列印級別,我們來驗證能夠動態的修改日誌級別

3)、能夠通過修改埠號,能夠修改專案執行的埠號

下面我們一個一個來驗證

1、配置修改後能否立即生效?

新增一個介面

@Slf4j
@RestController
public class TestController {

    @Value( "${date.value}" )
    String dateValue;

    @GetMapping("test1")
    public void test1() {
        log.info("當前配置中心的 dateValue 值 = {}",dateValue);
    }
}

步驟 :1)先請求介面一次。2)然後修改apollo配置中心。3)然後在請求一次該介面。

SpringBoot(19)---SpringBoot整合Apollo

結論 從圖中很明顯看出第一次和第二次請求的介面,返回的配置資訊已經不一樣了。說明配置是會時時更新的。而且當我在apollo介面修改配置的時候,

控制檯日誌也會輸出相關資訊。

2、動態修改日誌級別

我們來思考有沒有這麼一種需求,我們線上上的日誌級別一般是INFO級別的,主要記錄業務操作或者錯誤的日誌。那麼這個時候當線上環境出現問題希望輸出DEBUG

日誌資訊輔助排查的時候怎麼辦呢?

如果以前,我們可以會修改配置檔案,重新打包然後上傳重啟線上環境,以前確實是這麼做的。通過Apollo配置中心我們可以實現不用重啟專案,就可以實現讓日誌

基本從INFO變成DEBUG。下面我們來演示一番。

在專案啟動之前,我在application.yml配置了日誌級別是info模式。我們來請求下面介面驗證下。


 @GetMapping("test2")
    public void test2() {
      log.debug("我是 debug 列印出的日誌");
      log.info("我是 info 列印出的日誌");
      log.error("我是 error 列印出的日誌");
    }
    

請求下介面看下控制檯

SpringBoot(19)---SpringBoot整合Apollo

可以很明顯的看出,控制檯只列印info級別以上的日誌,並沒有列印debug日誌。

現在我們要做的是將列印日誌級別不在交給application.yml而是交給apollo來配置。這裡其實要做兩步:

1)、在apollo配置一條日誌資料

2)、通過監聽配置的變化,來達到熱更新的效果

java配置類

@Configuration
public class LoggerConfig {

    private static final Logger logger = LoggerFactory.getLogger(LoggerConfig.class);
    private static final String LOGGER_TAG = "logging.level.";

    @Autowired
    private LoggingSystem loggingSystem;

    @ApolloConfig
    private Config config;

    @ApolloConfigChangeListener
    private void configChangeListter(ConfigChangeEvent changeEvent) {
        refreshLoggingLevels();
    }

    @PostConstruct
    private void refreshLoggingLevels() {
        Set<String> keyNames = config.getPropertyNames();
        for (String key : keyNames) {
            if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
                String strLevel = config.getProperty(key, "info");
                LogLevel level = LogLevel.valueOf(strLevel.toUpperCase());
                loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);
                logger.info("{}:{}", key, strLevel);
            }
        }
    }

}

關鍵點講解

@ApolloConfig註解:將Apollo服務端的中的配置注入這個類中。

@ApolloConfigChangeListener註解:監聽配置中心配置的更新事件,若該事件發生,則呼叫refreshLoggingLevels方法,處理該事件。

ConfigChangeEvent引數:可以獲取被修改配置項的key集合,以及被修改配置項的新值、舊值和修改型別等資訊。

從上面可以看出,通過@PostConstruct 專案啟動的時候就去獲取apollo的日誌級別去覆蓋application.yml日誌級別。我在apollo配置中心,新增加一條日誌配置。

把日誌級別設定error,那麼在專案啟動的時候,因為PostConstruct註解的原因,所以會去執行一次refreshLoggingLevels方法,把當前日誌級別改成error

apollo配置

SpringBoot(19)---SpringBoot整合Apollo

我們重啟啟動專案再來看下,請求上面介面結果。

SpringBoot(19)---SpringBoot整合Apollo

從上圖我們就可以看出,我們同時在application.ymlapollo都配置了日誌列印級別,但實際上列印出來的結果來看,最終是以apollo為準。

現在我們再來嘗試下,我們修改apollo配置,把日誌級別修改成debug級別。

apollo配置

SpringBoot(19)---SpringBoot整合Apollo

因為我們在LoggerConfig中,有個 @ApolloConfigChangeListener註解,我們在修改配置的時候都會被監聽到,監聽到之後就會把當前的日誌級別,換成最新的。

我們再來請求介面,看下控制檯。

SpringBoot(19)---SpringBoot整合Apollo

總結 通過上面的驗證,可以得出:我在沒有重啟伺服器的情況下,實現了日誌級別動態切換的功能。

3、動態修改埠號

這裡我就不把驗證的過程發出來了,結論就是不可以。如果要驗證,在上面的refreshLoggingLevels方法中,加入修改埠的邏輯。

其實理由很簡單,因為埠跟程式繫結在一起的,你的程式起來了,埠就無法改變。如果一定要換埠號,那麼就需要有一個獨立程式,去殺掉你的專案程式,

再起一個新的不同埠的程式。顯然apollo沒有這樣的功能,而且個人覺得也沒啥意義。。

好了,整篇文章到這裡就結束了,下面把該專案的具體程式碼放到github上。

GitHub地址 :SpringBoot整合Apollo


參考

1、官方文件

2、SpringBoot 整合 apollo



別人罵我胖,我會生氣,因為我心裡承認了我胖。別人說我矮,我就會覺得好笑,因為我心裡知道我不可能矮。這就是我們為什麼會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(29)

相關文章