中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spring?boot微服務場景下apollo加載過程實例分析

發布時間:2022-02-21 14:44:56 來源:億速云 閱讀:127 作者:iii 欄目:開發技術

本篇內容主要講解“spring boot微服務場景下apollo加載過程實例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“spring boot微服務場景下apollo加載過程實例分析”吧!

    集成使用

    1、添加 gradle 依賴

    implementation "com.ctrip.framework.apollo:apollo-client:1.6.0"

    2、配置 application.properties

    apollo 自身的配置共包含 9 項,必要配置只有 3 項,其他的都是可選的配置。apollo 在 spring-boot 環境下的配置命名和 System 參數的命名保持了一直,最終 spring 的配置會注入到 System 中,具體的邏輯下文分析。

    必須配置
    #應用的ID
    app.id = java-project
    # apollo 的 config-service 服務發現地址
    apollo.meta = http://apollo.meta
    # 啟用 apollo
    apollo.bootstrap.enabled = true
    可選配置
    # 在日志系統初始化前加載 apollo 配置
    apollo.bootstrap.eagerLoad.enabled=true
    # 加載的命名空間,默認加載 application ,多個以逗號隔開
    apollo.bootstrap.namespaces = application
    # apollo 的安全拉取 secret 配置
    apollo.accesskey.secret = xx
    # 集群配置
    apollo.cluster = hk
    # 緩存路徑
    apollo.cacheDir = /opt
    # 是否保持和 apollo 配置頁面的配置順序一致
    apollo.property.order.enable = true

    加載過程解析

    public class ApolloApplicationContextInitializer implements ApplicationContextInitializer, EnvironmentPostProcessor, Ordered {
      public static final int DEFAULT_ORDER = 0;
      private static final Logger logger = LoggerFactory.getLogger(ApolloApplicationContextInitializer.class);
      private static final Splitter NAMESPACE_SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults();
      private static final String[] APOLLO_SYSTEM_PROPERTIES = {"app.id", ConfigConsts.APOLLO_CLUSTER_KEY,
          "apollo.cacheDir", "apollo.accesskey.secret", ConfigConsts.APOLLO_META_KEY, PropertiesFactory.APOLLO_PROPERTY_ORDER_ENABLE};
      private final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector.getInstance(ConfigPropertySourceFactory.class);
      private int order = DEFAULT_ORDER;
      @Override
      public void initialize(ConfigurableApplicationContext context) {
        ConfigurableEnvironment environment = context.getEnvironment();
        if (!environment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, Boolean.class, false)) {
          logger.debug("Apollo bootstrap config is not enabled for context {}, see property: ${{}}", context, PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED);
          return;
        }
        logger.debug("Apollo bootstrap config is enabled for context {}", context);
        initialize(environment);
      }
      /**
       * Initialize Apollo Configurations Just after environment is ready.
       *
       * @param environment
       */
      protected void initialize(ConfigurableEnvironment environment) {
        if (environment.getPropertySources().contains(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
          //already initialized
          return;
        }
        String namespaces = environment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_NAMESPACES, ConfigConsts.NAMESPACE_APPLICATION);
        logger.debug("Apollo bootstrap namespaces: {}", namespaces);
        ListnamespaceList = NAMESPACE_SPLITTER.splitToList(namespaces);
        CompositePropertySource composite = new CompositePropertySource(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME);
        for (String namespace : namespaceList) {
          Config config = ConfigService.getConfig(namespace);
          composite.addPropertySource(configPropertySourceFactory.getConfigPropertySource(namespace, config));
        }
        environment.getPropertySources().addFirst(composite);
      }
      /**
       * To fill system properties from environment config
       */
      void initializeSystemProperty(ConfigurableEnvironment environment) {
        for (String propertyName : APOLLO_SYSTEM_PROPERTIES) {
          fillSystemPropertyFromEnvironment(environment, propertyName);
        }
      }
      private void fillSystemPropertyFromEnvironment(ConfigurableEnvironment environment, String propertyName) {
        if (System.getProperty(propertyName) != null) {
          return;
        }
        String propertyValue = environment.getProperty(propertyName);
        if (Strings.isNullOrEmpty(propertyValue)) {
          return;
        }
        System.setProperty(propertyName, propertyValue);
      }
      /**
       *
       * In order to load Apollo configurations as early as even before Spring loading logging system phase,
       * this EnvironmentPostProcessor can be called Just After ConfigFileApplicationListener has succeeded.
       *
       * 
       * The processing sequence would be like this: 
       * Load Bootstrap properties and application properties -----> load Apollo configuration properties ----> Initialize Logging systems
       *
       * @param configurableEnvironment
       * @param springApplication
       */
      @Override
      public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {
        // should always initialize system properties like app.id in the first place
        initializeSystemProperty(configurableEnvironment);
        Boolean eagerLoadEnabled = configurableEnvironment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED, Boolean.class, false);
        //EnvironmentPostProcessor should not be triggered if you don't want Apollo Loading before Logging System Initialization
        if (!eagerLoadEnabled) {
          return;
        }
        Boolean bootstrapEnabled = configurableEnvironment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, Boolean.class, false);
        if (bootstrapEnabled) {
          initialize(configurableEnvironment);
        }
      }
      /**
       * @since 1.3.0
       */
      @Override
      public int getOrder() {
        return order;
      }
      /**
       * @since 1.3.0
       */
      public void setOrder(int order) {
        this.order = order;
      }
    }

    apollo 在 spring-boot 中的加載邏輯都在如上的代碼中了,代碼的關鍵是實現了兩個 spring 生命周期的接口,

    • ApplicationContextInitializer

    在被 ConfigurableApplicationContext.refresh()刷新之前初始化 ConfigurableApplicationContext 的回調接口。

    • EnvironmentPostProcessor

    比 ApplicationContextInitializer 的加載時機還要提前,此時 spring-boot 的日志系統還未初始化,

    postProcessEnvironment 方法邏輯解析

    1、初始化 System 的配置,將 spring 上下文中的配置(環境變量、System 參數、application.properties) 拷貝到 System 配置中, 如果 System 已經存在同名的配置則跳過,保證了 -D 設置的 System 參數的最高優先級。但是也帶來了一個隱含的問題,默認,apollo 的配置設計支持從環境變量中取值,也遵循了環境變量大寫的規范,將 System 參數的 "." 換成 "_" 拼接,然后變成大寫。 比如 apollo.meta 對應環境變量的 APOLLO_META。但是在 spring-boot 的環境下,因為 spring 的配置系統默認也會加載環境變量的配置,最終在環境變量里配置 apollo.meta 也會生效。甚至比正確配置的 APOLLO_META 環境變量值的優先級還高。

    2、根據 apollo.bootstrap.eagerLoad.enabled 和 apollo.bootstrap.enabled 的配置來判斷是否在這個階段初始化 apollo。 postProcessEnvironment() 執行的時候, 此時日志系統并未初始化,在這個階段加載 apollo,可以解決將日志配置托管到 apollo 里直接生效的問題。 帶來的問題是, 假如在這個階段的 apollo 加載出現問題,由于日志系統未初始化,看不到 apollo 的加載日志,不方便定位 apollo 的加載問題。 所以博主建議,如果有托管日志配置的場景,可以先不啟用 apollo.bootstrap.eagerLoad.enabled 的配置,等 apollo 集成完成后在啟用。

    initialize 方法邏輯解析

    1、根據 apollo.bootstrap.enabled 的配置來判斷,是否在這個階段初始化 apollo ,如果此時 spring 上下文中已經包含了 apollo 的 PropertySources,代表 apollo 已經 初始化過,則直接 return 掉

    2、根據 apollo.bootstrap.namespaces 的配置,默認不配置為 "application" ,依次獲取對應的 namespace 的配置, 并將配置使用 addFirst() 具有最高優先級屬性源的設置方法, 添加到了 spring 的配置上下文中。這里解釋了為什么 apollo 的配置的優先級最高,比 application.properties 中直接配置都要高, 這個優先級的問題會經常鬧烏龍,在本地開發調試階段,會直接在 application.properties 里調試配置,然后怎么改都不生效,因為 apollo 里 存在了同名的配置,啟動的時候直接覆蓋了本地的配置。

    到此,相信大家對“spring boot微服務場景下apollo加載過程實例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    寿宁县| 乌审旗| 平潭县| 古丈县| 于都县| 黑山县| 和静县| 三原县| 武义县| 元氏县| 常德市| 昌吉市| 赤水市| 扎鲁特旗| 象州县| 清水河县| 弋阳县| 宜兰县| 北宁市| 塔河县| 西林县| 遵化市| 南皮县| 响水县| 玉树县| 大同市| 榆社县| 贵德县| 水富县| 西青区| 娱乐| 河北区| 裕民县| 堆龙德庆县| 普陀区| 盘山县| 丘北县| 怀远县| 蒲江县| 陇西县| 桐庐县|