溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringBoot整合Apollo配置中心怎么用

發(fā)布時(shí)間:2021-09-24 11:06:15 來源:億速云 閱讀:377 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下SpringBoot整合Apollo配置中心怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

    一、簡(jiǎn)介

    1.Apollo 是什么?Apollo(阿波羅)是攜程框架部門研發(fā)的分布式配置中心。服務(wù)端基于Spring Boot和Spring Cloud開發(fā)。

    2.為什么要使用Apollo?

    • 安全性:配置跟隨源代碼保存在代碼庫中,容易造成配置泄漏

    • 時(shí)效性:普通方式配置,修改配置,需要重啟服務(wù)才能生效

    • 局限性:無法支持動(dòng)態(tài)調(diào)整:例如日志開關(guān)、功能開關(guān)

    二、使用

    1. 測(cè)試項(xiàng)目搭建

    注:本文主要介紹SpringBoot 整合 Apollo 實(shí)現(xiàn)動(dòng)態(tài)配置

    1.1 添加Maven依賴

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

    1.2 配置文件

    # apollo集成
    # apollo 配置應(yīng)用的 appid
    app.id=springboot-apollo-demo1
    # apollo meta-server地址,一般同config-server地址
    apollo.meta=http://192.168.0.153:8080
    #啟用apollo配置開關(guān)
    apollo.bootstrap.enabled=true
    apollo.bootstrap.eagerLoad.enabled=true
    # apollo 使用配置的命名空間,多個(gè)以逗號(hào)分隔
    apollo.bootstrap.namespaces = application

    配置說明:

    • app.id:在配置中心配置的應(yīng)用身份信息。

    • apollo.bootstrap.enabled:在應(yīng)用啟動(dòng)階段是否向Spring容器注入被托管的properties文件配置信息。

    • apollo.bootstrap.eagerLoad.enabled:將Apollo配置加載提到初始化日志系統(tǒng)之前。

    • apollo.bootstrap.namespaces:配置的命名空間,多個(gè)逗號(hào)分隔,一個(gè)namespace相當(dāng)于一個(gè)配置文件。

    • **apollo.meta:**當(dāng)前環(huán)境服務(wù)配置地址,生產(chǎn)環(huán)境建議至少雙節(jié)點(diǎn),可以填寫多個(gè)逗號(hào)分隔,使用一個(gè)單獨(dú)的域,如 http://config.xxx.com(由nginx等軟件負(fù)載平衡器支持),而不是多個(gè)IP地址,因?yàn)?a title="服務(wù)器" target="_blank" href="http://kemok4.com/">服務(wù)器可能會(huì)擴(kuò)展或縮小。

    圖示說明:

    SpringBoot整合Apollo配置中心怎么用

    1.3 添加啟動(dòng)類

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
    public class SpringbootApolloApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringbootApolloApplication.class, args);
        }
    }

    1.4 添加配置開關(guān)類

    基于@Value注解配置

    @Component
    public class ValueStyleProperty {
    
        @Value("${apollo.value.demoKey1}")
        private String demoKey1;
    
    
        @Value("${apollo.value.demoKey2}")
        private String demoKey2;
        //省略 get/set 方法
    }

    1.5 添加測(cè)試controller

    /**
     * value注解方式,獲取屬性
     *
     * @author mengqiang
     */
    @RestController
    @RequestMapping("/value-style")
    public class ValuePropertyController {
    
        @Autowired
        private ValueStyleProperty keyProperty;
    
        @Value("${server.port}")
        private String port;
    
        @Value("${apollo.bootstrap.namespaces:'application'}")
        private String namespaces;
    
        @GetMapping("/get")
        public Map<String, Object> getProperty() {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("port", port);
            map.put("namespaces", namespaces);
            map.put("demoKey1", keyProperty.getDemoKey1());
            map.put("demoKey2", keyProperty.getDemoKey2());
            return map;
        }
    }

    2. Apollo配置中心的配置

    2.1 創(chuàng)建項(xiàng)目

    SpringBoot整合Apollo配置中心怎么用

    2.2 填寫配置信息

    SpringBoot整合Apollo配置中心怎么用

    配置說明:

    • 部門:選擇應(yīng)用所在的部門。(可自定義部門)

    • 應(yīng)用AppId:用來標(biāo)識(shí)應(yīng)用身份的唯一id,格式為string,需與application.properties中配置的app.id一致。

    • 應(yīng)用名稱:應(yīng)用名,僅用于界面展示。

    • 應(yīng)用負(fù)責(zé)人:選擇的人默認(rèn)會(huì)成為該項(xiàng)目的管理員,具備項(xiàng)目權(quán)限管理、集群創(chuàng)建、Namespace創(chuàng)建等權(quán)限。

    項(xiàng)目配置主頁截圖

    SpringBoot整合Apollo配置中心怎么用

    2.3 添加配置

    2.3.1 表格形式單個(gè)添加

    注:不能批量操作

    SpringBoot整合Apollo配置中心怎么用

    SpringBoot整合Apollo配置中心怎么用

    2.3.2 文本形式批量添加

    注:可實(shí)現(xiàn)批量操作

    SpringBoot整合Apollo配置中心怎么用

    SpringBoot整合Apollo配置中心怎么用

    SpringBoot整合Apollo配置中心怎么用

    2.4 發(fā)布配置

    注:配置只有發(fā)布后才會(huì)生效

    SpringBoot整合Apollo配置中心怎么用

    點(diǎn)擊發(fā)布按鈕

    SpringBoot整合Apollo配置中心怎么用

    2.5 多環(huán)境同步配置

    注意事項(xiàng):

    通過同步配置功能,可以使多個(gè)環(huán)境、集群間的配置保持一致需要注意的是,同步完之后需要發(fā)布后才會(huì)對(duì)應(yīng)用生效

    點(diǎn)擊同步配置

    SpringBoot整合Apollo配置中心怎么用

    選擇需要同步的配置,以及目標(biāo)環(huán)境

    SpringBoot整合Apollo配置中心怎么用

    點(diǎn)擊同步

    SpringBoot整合Apollo配置中心怎么用

    目標(biāo)環(huán)境查看

    SpringBoot整合Apollo配置中心怎么用

    3. 項(xiàng)目啟動(dòng)與測(cè)試

    3.1 初始啟動(dòng)讀取測(cè)試

    SpringBoot整合Apollo配置中心怎么用

    3.2 自動(dòng)更新屬性測(cè)試

    SpringBoot整合Apollo配置中心怎么用

    發(fā)布后控制臺(tái)變化

    SpringBoot整合Apollo配置中心怎么用

    測(cè)試輸出值變化

    SpringBoot整合Apollo配置中心怎么用

    4.常見整合問題

    4.1@ConfigurationProperties注解整合Apollo不生效問題

    示例配置類

    /**
     * 公共開關(guān),key值 屬性配置
     *
     * @author mengqiang
     */
    @Component
    @ConfigurationProperties(prefix = "apollo.first.config")
    public class ConfigFirstProperty {
    
        /**
         * 測(cè)試數(shù)字
         */
        private Integer oneNumber;
    
        /**
         * 測(cè)試字符串
         */
        private String oneStr;
    
        /**
         * 啟用標(biāo)記
         */
        private Boolean oneEnableFlag;
    
        /**
         * 稅率 默認(rèn) 0.03
         */
        private BigDecimal oneTaxRate = new BigDecimal("0.03");
       //省略 get/set 方法
    
    }

    解決方案
    添加監(jiān)聽配置

    import com.ctrip.framework.apollo.model.ConfigChange;
    import com.ctrip.framework.apollo.model.ConfigChangeEvent;
    import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
    
    /**
     * Apollo 配置監(jiān)聽
     */
    @Configuration
    public class ApolloConfigListener implements ApplicationContextAware {
    
        /**
         * 日志
         */
        private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigListener.class);
    
        private ApplicationContext applicationContext;
    
       /**
         * 配置監(jiān)聽
         * ApolloConfigChangeListener > value 屬性默認(rèn) 命名空間 "application"
         *
         * 示例: @ApolloConfigChangeListener(value = {"application", "test_space"})
         */
        @ApolloConfigChangeListener
        private void onChange(ConfigChangeEvent changeEvent) {
            LOGGER.info("【Apollo-config-change】start");
            for (String key : changeEvent.changedKeys()) {
                ConfigChange change = changeEvent.getChange(key);
                LOGGER.info("key={} , propertyName={} , oldValue={} , newValue={} ", key, change.getPropertyName(), change.getOldValue(), change.getNewValue());
            }
            // 更新相應(yīng)的bean的屬性值,主要是存在@ConfigurationProperties注解的bean
            this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
    
            LOGGER.info("【Apollo-config-change】end");
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }

    4.2日志級(jí)別未更新問題

    示例配置

    logging.level.com.example=info

    解決方案-日志監(jiān)聽器

    import com.ctrip.framework.apollo.model.ConfigChange;
    import com.ctrip.framework.apollo.model.ConfigChangeEvent;
    import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.logging.LogLevel;
    import org.springframework.boot.logging.LoggingSystem;
    import org.springframework.context.annotation.Configuration;
    import javax.annotation.Resource;
    
    /**
     * Apollo 日志-配置監(jiān)聽
     */
    @Configuration
    public class LoggerConfigListener {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConfigListener.class);
        private static final String LOGGER_TAG = "logging.level.";
    
        @Resource
        private LoggingSystem loggingSystem;
    
        /**
         * 監(jiān)聽 日志配置的變化
         */
        @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG)
        private void onChangeLogger(ConfigChangeEvent changeEvent) {
            LOGGER.info("【Apollo-logger-config-change】>> start");
            refreshLoggingLevel(changeEvent);
            LOGGER.info("【Apollo-logger-config-change】>> end");
        }
    
        /**
         * 刷新日志級(jí)別
         */
        private void refreshLoggingLevel(ConfigChangeEvent changeEvent) {
            if (null == loggingSystem) {
                return;
            }
            for (String key : changeEvent.changedKeys()) {
                ConfigChange change = changeEvent.getChange(key);
                if (!StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
                    continue;
                }
                LOGGER.info("【Apollo-logger-config-change】>> key={} , propertyName={} , oldValue={} , newValue={} ",
                        key, change.getPropertyName(), change.getOldValue(), change.getNewValue());
                String newLevel = change.getNewValue();
                LogLevel level = LogLevel.valueOf(newLevel.toUpperCase());
                loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);
                LOGGER.info("【Apollo-logger-config-change】>> {} -> {}", key, newLevel);
            }
        }
    }

    4.3日志+配置類自動(dòng)刷新整合監(jiān)聽

    注:由于 4.1與4.2監(jiān)聽有重合,所以最好放在一起處理

    import com.ctrip.framework.apollo.model.ConfigChange;
    import com.ctrip.framework.apollo.model.ConfigChangeEvent;
    import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.boot.logging.LogLevel;
    import org.springframework.boot.logging.LoggingSystem;
    import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.context.annotation.Configuration;
    import javax.annotation.Resource;
    
    /**
     * Apollo 配置監(jiān)聽
     */
    @Configuration
    public class ApolloConfigListener implements ApplicationContextAware {
        /**
         * 日志
         */
        private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigListener.class);
        /**
         * 日志配置常量
         */
        private static final String LOGGER_TAG = "logging.level.";
    
        @Resource
        private LoggingSystem loggingSystem;
    
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
    
        /**
         * 配置監(jiān)聽
         * ApolloConfigChangeListener > value 屬性默認(rèn) 命名空間 "application"
         */
        @ApolloConfigChangeListener
        private void onChangeConfig(ConfigChangeEvent changeEvent) {
            LOGGER.info("【Apollo-config-change】>> start");
            for (String key : changeEvent.changedKeys()) {
                ConfigChange change = changeEvent.getChange(key);
                LOGGER.info("【Apollo-config-change】>> key={} , propertyName={} , oldValue={} , newValue={} ",
                        key, change.getPropertyName(), change.getOldValue(), change.getNewValue());
                //是否為日志配置
                if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
                    //日志配置刷新
                    changeLoggingLevel(key, change);
                    continue;
                }
                // 更新相應(yīng)的bean的屬性值,主要是存在@ConfigurationProperties注解的bean
                this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
            }
            LOGGER.info("【Apollo-config-change】>> end");
        }
    
        /**
         * 刷新日志級(jí)別
         */
        private void changeLoggingLevel(String key, ConfigChange change) {
            if (null == loggingSystem) {
                return;
            }
            String newLevel = change.getNewValue();
            LogLevel level = LogLevel.valueOf(newLevel.toUpperCase());
            loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);
            LOGGER.info("【Apollo-logger-config-change】>> {} -> {}", key, newLevel);
        }
    }

    4.4 其它問題

    4.4.1配置文件與配置中心同時(shí)存在配置,啟用的是那一份
    apollo 配置開關(guān)開啟情況下,配置中心配置會(huì)覆蓋本地配置
    注:配置開關(guān) apollo.bootstrap.enabled=true

    4.4.2 配置中心掛掉會(huì)影響已發(fā)布的項(xiàng)目嗎?
    項(xiàng)目啟動(dòng)后配置會(huì)存在緩存中,配置中心掛掉,已發(fā)布的項(xiàng)目不影響

    4.4.3 是否支持更新端口配置
    支持更新端口配置,但是必需要重啟生效,同時(shí)也需要考慮服務(wù)器的端口占用問題。

    以上是“SpringBoot整合Apollo配置中心怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI