Nacos做配置中心


 從單體架構到微服務

單體架構
Web應用程序發展的早期,大部分web工程師將所有的功能模塊打包到一起並放在一個web容器中運行,所有功能
模塊使用同一個數據庫,同時,它還提供API或者UI訪問的web模塊等。

 

盡管也是模塊化邏輯,但是最終它還是會打包並部署為單體式應用,這種將所有功能都部署在一個web容器中運行
的系統就叫做單體架構(也叫:巨石型應用)。
單體架構有很多好處:

  • 開發效率高:模塊之間交互采用本地方法調用,並節省微服務之間的交互討論時間與開發成本。
  • 容易測試:IDE都是為開發單個應用設計的、容易測試——在本地就可以啟動完整的系統。
  • 容易部署:運維成本小,直接打包為一個完整的包,拷貝到web容器的某個目錄下即可運行。

但是,上述的好處是有條件的,它適用於小型簡單應用,對於大規模的復雜應用,就會展現出來以下的不足:

  • 復雜性逐漸變高,可維護性逐漸變差 :所有業務模塊部署在一起,復雜度越來越高,修改時牽一發動全身。
  • 版本迭代速度逐漸變慢:修改一個地方就要將整個應用全部編譯、部署、啟動時間過長、回歸測試周期過長。
  • 阻礙技術創新:若更新技術框架,除非你願意將系統全部重寫,無法實現部分技術更新。
  • 無法按需伸縮:通過冗余部署完整應用的方式來實現水平擴展,無法針對某業務按需伸縮。

微服務
許多大型公司,通過采用微服務架構解決了上述問題。其思路不是開發一個巨大的單體式的應用,而是將應用分解為小的、互相連接的微服務。
一個微服務一般完成某個特定的功能,比如訂單服務、用戶服務等等。每一個微服務都是完整應用,都有自己的業務邏輯和數據庫。一些微服務還會發布API給其它微服務和應用客戶端使用。
比如,根據前面描述系統可能的分解如下:

 

每一個業務模塊都使用獨立的服務完成,這種微服務架構模式也影響了應用和數據庫之間的關系,不像傳統多個業務模塊共享一個數據庫,微服務架構每個服務都有自己的數據庫。
微服務架構的好處:

  • 分而治之,職責單一;易於開發、理解和維護、方便團隊的拆分和管理
  • 可伸縮;能夠單獨的對指定的服務進行伸縮
  • 局部容易修改,容易替換,容易部署,有利於持續集成和快速迭代
  • 不會受限於任何技術棧

 分布式應用配置管理
下圖展示了如何通過Nacos集中管理多個服務的配置:

 

用戶通過 Nacos Server的控制台集中對多個服務的配置進行管理。各服務統一從 Nacos Server中獲取各自的配置,並監聽配置的變化。

發布配置
首先在nacos發布配置,我們規划了兩個服務service1、service2,並且想對這兩個服務的配置進行集中維護。打開nacos控制台,並點擊菜單配置管理->配置列表:
在Nacos添加如下的配置:

 

創建項目

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.3.RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement> 

啟動類:

@SpringBootApplication
@RestController
public class Service1Application {

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

    @Autowired
    ConfigurableApplicationContext applicationContext;

    @GetMapping("/port")
    public String getPort() {
        //讀取配置信息
       return applicationContext.getEnvironment().getProperty("server.port");
    }

    @GetMapping("/configs")
    public String getConfigs() {
        //讀取配置信息
        return applicationContext.getEnvironment().getProperty("common.name");
    }

    @GetMapping(value = "/configs2")
    public String getConfigs2() {
        String name = applicationContext.getEnvironment().getProperty("common.name");
        String age = applicationContext.getEnvironment().getProperty("common.age");
        String address = applicationContext.getEnvironment().getProperty("common.address");
        String birthday = applicationContext.getEnvironment().getProperty("common.birthday");
        String fullname = applicationContext.getEnvironment().getProperty("common.fullname");
        return name + "+" + age + "+" + address + "+" + birthday + "+" + fullname;
    }

}  

配置

spring:
  application:
    name: service1
  cloud:
    nacos:
      config:
        server-addr: 47.156.271.569:8848  # 配置中心地址
        file-extension: yaml #dataid 的名稱就是application的name加file-extension   service1.yaml
        namespace: e4582490-173d-41df-9932-c65f01605814 # 開發環境  指定 具體的namespace
        group: TEST_GROUP # 測試組  

開始測試,直接在線修改,支持動態刷新

 

 

 支持擴展dataid

配置如下:

spring:
  application:
    name: service1
  cloud:
    nacos:
      config:
        server-addr: 47.111.251.239:8848  # 配置中心地址
        file-extension: yaml #dataid 的名稱就是application的name加file-extension   service1.yaml
        namespace: e4582490-173d-41df-9932-c65f01605814 # 開發環境  指定 具體的namespace
        group: TEST_GROUP # 測試組
        ext-config:
          - data-id: service2.yaml
            group: TEST_GROUP
            refresh: true
#        ext-config[0]:
#          data-id: service2.yaml
#          group: TEST_GROUP
#          refresh: true  

上圖中的2種配置都可以,上面是即定義了group和支持刷新。 

可以看到 :

  • 通過 spring.cloud.nacos.config.ext -config[n].data-id 的配置方式來支持多個 Data Id 的配置。
  • 通過 spring.cloud.nacos.config.ext -config[n].group 的配置方式自定義 Data Id 所在的組,不明確配置的話,默認是 DEFAULT_GROUP。
  • 通過 spring.cloud.nacos.config.ext -config[n].refresh 的配置方式來控制該 Data Id 在配置變更時,是否支持應用中可動態刷新, 感知到最新的配置值。默認是不支持的

Note : spring.cloud.nacos.config.ext -config[n].data-id 的值必須帶文件擴展名,文件擴展名既可支持properties,又可以支持 yaml/yml。 此時 spring.cloud.nacos.config.file -extension 的配置對自定義擴
展配置的 Data Id 文件擴展名沒有影響。

通過自定義擴展的 Data Id 配置,既可以解決多個應用間配置共享的問題,又可以支持一個應用有多個配置文件。

 自定義共享 Data Id 配置
為了更加清晰的在多個應用間配置共享的 Data Id ,你可以通過以下的方式來配置:

 注意:共享dataid的時候默認DEFAULT_GROUP,不是這個組的話,是讀取不到的

spring:
  application:
    name: service1
  cloud:
    nacos:
      config:
        server-addr: 47.151.545.265:8848  # 配置中心地址
        file-extension: yaml #dataid 的名稱就是application的name加file-extension   service1.yaml
        namespace: e4582490-173d-41df-9932-c65f01605814 # 開發環境  指定 具體的namespace
        group: TEST_GROUP # 測試組
        shared-dataids: ext-config-common01.properties,ext-config-common02.properties,ext-config-common03.properties
        refreshable-dataids: ext-config-common01.properties

可以看到:

  • 通過 spring.cloud.nacos.config.shared -dataids 來支持多個共享 Data Id 的配置,多個之間用逗號隔開。
  • 通過 spring.cloud.nacos.config.refreshable -dataids 來支持哪些共享配置的 Data Id 在配置變化時,應用中是否可動態刷新, 感知到最新的配置值,多個 Data Id 之間用逗號隔開。如果沒有明確配置,默認情況下所有共享配置的 Data Id 都不支持動態刷新。

Note:通過 spring.cloud.nacos.config.shared -dataids 來支持多個共享配置的 Data Id 時, 多個共享配置間的一個優先級的關系我們約定:按照配置出現的先后順序,即后面的優先級要高於前面。
Note:通過 spring.cloud.nacos.config.shared -dataids 來配置時,Data Id 必須帶文件擴展名,文件擴展名既可支持 properties,也可以支持 yaml/yml。 此時 spring.cloud.nacos.config.file -extension 的配置對自定義擴展配置的 Data Id 文件擴展名沒有影響。
Note: spring.cloud.nacos.config.refreshable -dataids 給出哪些需要支持動態刷新時,Data Id 的值也必須明確給出文件擴展名。

配置的優先級
Spring Cloud Alibaba Nacos Config 目前提供了三種配置能力從 Nacos 拉取相關的配置。
A: 通過 spring.cloud.nacos.config.shared -dataids 支持多個共享 Data Id 的配置
B: 通過 spring.cloud.nacos.config.ext -config[n].data-id 的方式支持多個擴展 Data Id 的配置,多個Data Id 同時配置時,他的優先級關系是 spring.cloud.nacos.config.ext -config[n].data-id 其中 n 的值越大,優先級越高。
C: 通過內部相關規則(應用名、擴展名 )自動生成相關的 Data Id 配置
當三種方式共同使用時,他們的一個優先級關系是:C > B >A

完全關閉配置
通過設置 spring.cloud.nacos.config.enabled = false 來完全關閉 Spring Cloud Nacos Config


免責聲明!

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



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