SpringCloud中使用Nacos作為配置中心原理


 

使用了是Nacos的自動配置依賴

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

bootstrap.yml配置文件

spring:
  cloud:
    nacos:
      # Nacos 控制台添加配置:
      # Data ID:example.properties
      # Group:DEFAULT_GROUP
      config:
        server-addr: 127.0.0.1:8848
        prefix: example
        # 指定配置的后綴,支持 properties、yaml、yml,默認為 properties
        file-extension: properties
        username: nacos
        password: nacos

 

使用到nacos配置中心的bean上配置@RefreshScope 注解,標識這個bean的作用域

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
    @Value("${useLocalCache:false}")
    private boolean useLocalCache;
    
    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}

 

以上面的配置為例子。

先說下具體配置點

1、加載的nacos屬性源列表有哪些?

默認會加載 group=DEFAULT_GROUP的屬性源列表有:

1、帶profile的 dataId配置源 dataId = ${prefix}-${spring.profiles.active}.${file-extension}

2、不帶profile的 dataId配置源 dataId = ${prefix}.${file-extension}

3、不帶后綴的 dataId配置源 dataId = ${prefix}

默認情況下 前綴 prefix = spring.application.name

加載屬性源列表優先級為:

帶profile的 DataId名稱 > 帶 .后綴的 dataId名稱 > 不帶 .后綴的 dataId名稱

如上面的配置按照優先級,從高到底會加載

dataId = example-dev.properties
dataId = example.properties dataId = example

 

2、nacos屬性源是否覆蓋本地配置文件和系統屬性的設置

SpringCloud中,nacos是借助SpringCloud的Config來加載屬性源的,所以是否覆蓋系統屬性和配置文件屬性的設置也是通過SpringCloud的配置進行觸發。

默認情況下的配置:

spring:
  cloud:
    config:
      # 是否不覆蓋其他屬性源,默認為false,即覆蓋其他源
      override-none: false
      # 允許nacos被本地文件覆蓋,默認為true
      allow-override: true
      # 是否覆蓋系統屬性源,默認為true
      override-system-properties: true

 默認情況下nacos屬性源優先級最高,會覆蓋系統屬性源和配置屬性源。

 
如果用戶想復寫上述的屬性,則放在bootstrap.yml或application.yml配置文件中是無效的

如果要修改nacos的屬性源優先級,則需要將 上述配置放到nacos上的配置內容中才生效!

當nacos屬性源中有上面的配置參數時
會先判斷
1、(!allow-override || (!override-none && override-system-properties))
    上面條件為真時,
    override-none: false
    allow-override: true
    override-system-properties: true
    會將nacos屬性源添加到 environment的屬性源列表第一位,
    即覆蓋系統屬性源,並且可以覆蓋其他屬性源
    propertySources.addFirst()

2、(override-none)
    不滿足條件1,且條件2為真時。
    override-none: true
    allow-override: true
    override-system-properties: true
    即不覆蓋其他屬性源,將nacos屬性源放到屬性源列表最后面。
    propertySources.addLast()

3override-system-properties = false時,
    不滿足條件1和2,上面條件通過
    會將nacos屬性源添加到 系統屬性源(systemEnvironment)后面,在其他配置文件之前。
    

所以當要讓nacos優先級最高,使用默認spring.cloud.config配置即可。
當要讓nacos屬性源不覆蓋本地配置文件,需要設置 override-none: true
當要讓nacos屬性源覆蓋本地配置文件,但不覆蓋系統屬性源,設置 override-system-properties: false

 

 

啟動過程:

1、SpringBoot的prepareEnvironment()方法初始化完系統環境屬性源后,

  發布環境准備完成事件中,進行SpringCloud容器啟動,會在這里進行Nacos的配置源加載到Environment中。

2、Nacos動態刷新配置屬性相關bean定義的設置(@RefreshScope注解配置)

  @RefreshScope 注解標識 bean的生命周期(作用域)

@RefreshScope標識的bean:標識bean的生命周期為當前配置沒發生變化的時間段內。

    即:當配置文件發生變化(配置content的MD5值發生變化時),

    會觸發作用域:refresh的刷新操作。將會重新創建bean實例,放入到作用域bean實例列表中。

  具體查看資料:Spring系列四:Bean Scopes作用域:https://my.oschina.net/merryyou/blog/3119993

  如request作用域,標識為@RequestScope注解的bean,即等同於@Scope(WebApplicationContext.SCOPE_REQUEST),

    該bean的聲明周期為一次http請求開始到結束。即每一次獲取http請求獲取到的bean對象實例都是新創建的。

    而在一個http請求內引用的bean對象實例都是相同的對象。

啟動過程中作用域

如上面實例:ConfigController

有@RefreshScope注解,會被歸類到作用域refresh下面,bean的創建,銷毀都是由作用域來管理。

通過BeanFactory.getBean(String name) 方法獲取 ConfigController實例時,

  會判斷該bean是否屬於Singleton單例, Prototype原型 類型

  如果都不是,則會用Scope作用域來獲取bean實例。

  Scope.get(String name, ObjectFactory<?> objectFactory)方法

refresh作用域對應的Scope實現類: RefreshScope

 

 

SpringBoot運行過程中配置的刷新:

在自動配置類com.alibaba.cloud.nacos.NacosConfigAutoConfiguration
申明的配置刷新類:NacosContextRefresher
刷新事件處理類:RefreshEventListener 和 ContextRefresher

 當有配置變更時發布RefreshEvent事件,這個事件是RefreshEventListener監聽

NacosConfigService內部維持了一個executor輪詢線程(單線程,每隔0.01秒執行一次)和一個executorService處理數據線程。
輪詢線程會檢查配置數據的md5是否變化,發生變化再通知listener進行配置變更接收。

 

NacosContextRefresher向Nacos注冊的監聽器,會發布RefreshEvent事件
后面就通過Spring Cloud的刷新機制,進行環境配置屬性的重新加載。對 scope作用域中 key為 "refresh" 下的bean進行重新生成。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM