Nacos 筆記

程式設計師自由之路發表於2021-08-12

Nacos 筆記

本文件基於v2.0.3進行整理。

1. Nacos簡介

Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務後設資料及流量管理。(配置中心和註冊中心

1.1 主流配置中心對比

目前市面上用的比較多的配置中心有:Spring Cloud Confifig、Apollo、Nacos和Disconf等。 由於Disconf不再維護,下面主要對比一下Spring Cloud Confifig、Apollo和Nacos。

從配置中心角度來看,效能方面Nacos的讀寫效能最高,Apollo次之,Spring Cloud Confifig依賴Git場景不適合開 放的大規模自動化運維API。功能方面Apollo最為完善,nacos具有Apollo大部分配置管理功能,而Spring Cloud Confifig不帶運維管理介面,需要自行開發。Nacos的一大優勢是整合了註冊中心、配置中心功能,部署和操作相比 Apollo都要直觀簡單,因此它簡化了架構複雜度,並減輕運維及部署工作。

綜合來看,Nacos的特點和優勢還是比較明顯的,下面我們一起進入Nacos的世界。

1.2 主流注冊中心對比

目前市面上用的比較多的服務發現中心有:Nacos、Eureka、Consul和Zookeeper。

image-20210811164951654

1.3 Nacos特性

Nacos主要提供以下四大功能:

  1. 服務發現與服務健康檢查

    Nacos使服務更容易註冊,並通過DNS或HTTP介面發現其他服務,Nacos還提供服務的實時健康檢查,以防止向不健康的主機或服務例項傳送請求。

  2. 動態配置管理

    動態配置服務允許您在所有環境中以集中和動態的方式管理所有服務的配置。Nacos消除了在更新配置時重新部署應用程式,這使配置的更改更加高效和靈活。

  3. 動態DNS服務

    Nacos提供基於DNS 協議的服務發現能力,旨在支援異構語言的服務發現,支援將註冊在Nacos上的服務以域名的方式暴露端點,讓三方應用方便的查閱及發現。

  4. 服務和後設資料管理

    Nacos 能讓您從微服務平臺建設的視角管理資料中心的所有服務及後設資料,包括管理服務的描述、生命週期、服務的靜態依賴分析、服務的健康狀態、服務的流量管理、路由及安全策略。

這裡動態配置管理的特性說明了Naocs的配置管理能力。

2. 安裝啟動

安裝啟動

支援外部 MySQL

單機模式時nacos預設使用嵌入式資料庫實現資料的儲存,若想使用外部mysql儲存nacos資料,需要進行以下步驟:

  • 初始化mysql資料庫,新建資料庫nacos_confifig,資料庫初始化檔案:${nacoshome}/conf/nacos-mysql.sql
  • 修改${nacoshome}/conf/application.properties檔案,增加支援mysql資料來源配置(目前只支援mysql),新增mysql資料來源的url、使用者名稱和密碼。
spring.datasource.platform=mysql 
db.num=1 
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_config? characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true 
db.user=nacos_devtest 
db.password=youdontknow

注意:支援MySQL 8需要新增外掛。

3. 配置管理

3.1 什麼是配置中心

什麼是配置?

應用程式在啟動和執行的時候往往需要讀取一些配置資訊,配置基本上伴隨著應用程式的整個生命週期,比如:資料庫連線引數、啟動引數等。

配置主要有以下幾個特點:

  • 配置是獨立於程式的只讀變數

    • 配置對於程式是隻讀的,程式通過讀取配置來改變自己的行為,但是程式不應該去改變配置;
  • 配置伴隨應用的整個生命週期

    • 配置貫穿於應用的整個生命週期,應用在啟動時通過讀取配置來初始化,在執行時根據配置調整行為。比如:啟動時需要讀取服務的埠號、系統在執行過程中需要讀取定時策略執行定時任務等。
  • 配置可以有多種載入方式

    • 常見的有程式內部hard code,配置檔案,環境變數,啟動引數,基於資料庫等
  • 配置需要治理

    • 同一份程式在不同的環境(開發,測試,生產)、不同的叢集(如不同的資料中心)經常需要有不同的配置,所以需要有完善的環境、叢集配置管理

什麼是配置中心?

總得來說,配置中心就是一種統一管理各種應用配置的基礎服務元件。

在傳統巨型單體應用紛紛轉向細粒度微服務架構的歷史程式中,配置中心是微服務化不可缺少的一個系 統元件,在這種背景下中心化的配置服務即配置中心應運而生,一個合格的配置中心需要滿足如下特性:

  • 配置項容易讀取和修改
  • 分散式環境下應用配置的可管理性,即提供遠端管理配置的能力
  • 支援對配置的修改的檢視以把控風險
  • 可以檢視配置修改的歷史記錄
  • 不同部署環境下應用配置的隔離性

3.2 Nacos 配置入門(Spring-Boot形式)

step1:使用Nacos的介面釋出配置

image-20210809191741378

image-20210809191824668

step2:通過Nacos API獲取配置

/**
 * 演示使用Nacos API 對配置中心資料進行增刪改查的過程
 */
public class NacosApiDemo {
    public static void main(String[] args) throws NacosException, InterruptedException {
        String serverAddr = "localhost";
        String dataId = "application.yml";
        String group = "demo";
        String nameSpace = "6f97a206-ce19-44c2-85be-c601170d306e";
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, nameSpace);
        ConfigService configService = NacosFactory.createConfigService(properties);

        // 啟動的時候讀取配置中心的配置
        String content = configService.getConfig(dataId, group, 5000);
        System.out.println("配置內容:");
        System.out.println(content);

        // 監聽配置中心資料的變化
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("recieve:" + configInfo);
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });

        // 向資料中心推送資料,改變原有配置
        boolean isPublishOk = configService.publishConfig(dataId, group, "content");
        System.out.println(isPublishOk);

        //再次讀取資料
        Thread.sleep(3000);
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);

        // 刪除配置中心資料
        boolean isRemoveOk = configService.removeConfig(dataId, group);
        System.out.println(isRemoveOk);
        Thread.sleep(3000);

        // 再次讀書資料
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        Thread.sleep(300000);

    }
}

3.3 Web介面基本使用

Nacos 配置管理模型

對於Nacos配置管理,通過Namespace、group、Data ID能夠定位到一個配置集。

image-20210809200735604

配置集(Data ID)

在系統中,一個配置檔案通常就是一個配置集,一個配置集可以包含了系統的各種配置資訊,例如,一個配置集可 能包含了資料來源、執行緒池、日誌級別等配置項。每個配置集都可以定義一個有意義的名稱,就是配置集的ID即Data ID。

配置項

配置集中包含的一個個配置內容就是配置項。它代表一個具體的可配置的引數與其值域,通常以 key=value 的形 式存在。例如我們常配置系統的日誌輸出級別(logLevel=INFO|WARN|ERROR) 就是一個配置項。

配置分組(Group)

配置分組是對配置集進行分組,通過一個有意義的字串(如 Buy 或 Trade )來表示,不同的配置分組下可以有 相同的配置集(Data ID)。當您在 Nacos 上建立一個配置時,如果未填寫配置分組的名稱,則配置分組的名稱默 認採用 DEFAULT_GROUP 。配置分組的常見場景:可用於區分不同的專案或應用,例如:學生管理系統的配置集 可以定義一個group為:STUDENT_GROUP。

名稱空間(Namespace)

名稱空間(namespace)可用於進行不同環境的配置隔離。例如可以隔離開發環境、測試環境和生產環境,因為 它們的配置可能各不相同,或者是隔離不同的使用者,不同的開發人員使用同一個nacos管理各自的配置,可通過 namespace隔離。不同的名稱空間下,可以存在相同名稱的配置分組(Group) 或 配置集。

最佳實踐

Nacos抽象定義了Namespace、Group、Data ID的概念,具體這幾個概念代表什麼,取決於我們把它們看成什 麼,這裡推薦給大家一種用法,如下圖:

image-20210809201209744

名稱空間的管理

namespace 的設計是 nacos 基於此做多環境以及多租戶(多個使用者共同使用nacos)資料(配置和服務)隔離的。

  • 從一個租戶(使用者)的角度來看,如果有多套不同的環境,那麼這個時候可以根據指定的環境來建立不同的 namespce,以此來實現多環境的隔離。例如,你可能有開發,測試和生產三個不同的環境,那麼使用一套 nacos 叢集可以分別建以下三個不同的 namespace。如下圖所示:

    image-20210809203504494

  • 從多個租戶(使用者)的角度來看,每個租戶(使用者)可能會有自己的 namespace,每個租戶(使用者)的配置資料以及注 冊的服務資料都會歸屬到自己的 namespace 下,以此來實現多租戶間的資料隔離。例如超級管理員分配了三 個租戶,分別為張三、李四和王五。分配好了之後,各租戶用自己的賬戶名和密碼登入後,建立自己的命名 空間。如下圖所示:

    image-20210809203629892

Nacos介面使用(配置管理)

image-20210809205136793

上面監聽查詢的功能說下:可以通過IP地址查詢,查詢client端已經讀取到的配置檔案的MD5值,用這個MD5值和配置檔案詳情中的MD5值對比就可以知道客戶端拿到的配置檔案是不是最新的。

Spring-Cloud 整合Nacos

將演示如何使用 Spring Cloud Alibaba Nacos ConfifigSpring Cloud應用中整合Nacos,通過 Spring cloud原生方式快捷的獲取配置內容。

Spring Cloud是什麼:

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、訊息匯流排、負載均衡、斷路器、資料監控等,都可以用Spring Boot 的開發風格做到一鍵啟動和部署。Spring Cloud並沒有重複製造輪子,它只是將目前各家公司開發的比較成 熟、經得起實際考驗的服務框架組合起來,整合最多的元件要屬Netflflix公司,通過Spring Boot風格進行再封 裝遮蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分散式系統開發 工具包。

Spring Cloud Alibaba Nacos Confifig是什麼:

Spring Cloud Alibaba Nacos Confifig是Spring Cloud Alibaba的子專案,而Spring Cloud Alibaba是阿里巴巴公司提供的開源的基於Spring cloud的微服務套件合集,它致力於提供微服務開發的一站式解決方案,可以理解為spring cloud是一套微服務開發的 標準 ,spring cloud alibaba與spring cloud Netflflix是實現。使用 Spring Cloud Alibaba方案,開發者只需要新增一些註解和少量配置,就可以將 Spring Cloud 應用接入阿里分散式應用解決方案,通過阿里中介軟體來迅速搭建分散式應用系統。

step1:新增依賴

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
         <version>2.2.6.RELEASE</version>
     </dependency>
</dependencies>

step2:新增配置(bootstrap.yml)

#日誌配置
logging:
  config: classpath:logback-app.xml

#Server相關配置
server:
  port: ${port:9999}

#Spring相關配置
spring:
  application:
    name: cloud-app
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-exetension: yaml
        namespace: 6f97a206-ce19-44c2-85be-c601170d306e
        group: demo

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 預設為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。
  • spring.profiles.active 即為當前環境對應的 profile,詳情可以參考 Spring Boot文件注意:當 spring.profiles.active 為空時,對應的連線符 - 也將不存在,dataId 的拼接格式變成 ${prefix}.${file-extension}
  • file-exetension 為配置內容的資料格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前只支援 propertiesyaml 型別。

step3:通過 Spring Cloud 原生註解 @RefreshScope 實現配置自動更新

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}

自定義配置(data-id)

共享配置檔案

  • 團隊內部的專案共享配置檔案
spring:
  application:
    name: server1
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.2:8848
        file-extension: yaml
        namespace: 6f97a206-ce19-44c2-85be-c601170d306e
        group: demo
        # 這邊的shared-configs不能配置namespace,和上面的配置共享一個namespace,所以一般用於讀取一個團隊內部的共享檔案
        shared-configs[0]:
         data-id: common.yaml
         refresh: true
         group: common
  • 一個專案有多個配置檔案的情況
spring:
  application:
    name: server1
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.2:8848
        file-extension: yaml
        namespace: 6f97a206-ce19-44c2-85be-c601170d306e
        group: demo
        extensionConfigs[0]:
          data-id: jdbc.yaml
          refresh: true
          group: demo
        extensionConfigs[1]:
          data-id: o32.yaml
          refresh: true
          group: demo
        shared-configs[0]:
          data-id: common.yaml
          refresh: true
          group: common

配置檔案優先順序

假如依賴的配置檔案有衝突。

主配置檔案(通過nacos配置確定的配置檔案)> 擴充套件配置1 > 擴充套件配置0 > 公共配置

4. 服務發現

微服務環境下,服務經常是多例項部署的。而且經常會增加例項或者下線例項,服務之前怎麼互相感知,就是服務發現需要研究的問題。

總結一下,在微服務環境中,由於服務執行例項的網路地址是不斷動態變化的,服務例項數量的動態變化 ,因此無 法使用固定的配置檔案來記錄服務提供方的網路地址,必須使用動態的服務發現機制用於實現微服務間的相互感知。各服務例項會上報自己的網路地址,這樣服務中心就形成了一個完整的服務登錄檔,各服務例項會通過服務發現中心來獲取訪問目標服務的網路地址,從而實現服務發現的機制。

4.1 Nacos 服務發現快速入門

image-20210811171857774

採用Feign+Ribbon的整合方式,是由Feign完成遠端呼叫的整個流程。而Feign整合了Ribbon,Feign使用Ribbon

完成呼叫例項的負載均衡。 (Feign做遠端呼叫,Ribbon用來做負載均衡)

Ribbon 簡介

Ribbon是一個客戶端負載均衡器,它的責任是從一組例項列表中挑選合適的例項,如何挑選?取決於負載均衡策略

Ribbon核心元件IRule是負載均衡策略介面,它有如下實現:

image-20210811172445596

可通過下面方式在spring boot 配置檔案中修改預設的負載均衡策略:

account‐service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

account-service 是呼叫的服務的名稱,後面的組成部分是固定的。

Feign介紹

Feign是Netflflix開發的宣告式、模板化的HTTP客戶端, Feign可以幫助我們更快捷、優雅地呼叫HTTP API。Feign 的英文表意為“假裝,偽裝,變形”, 可以理解為將HTTP報文請求方式偽裝為簡單的java介面呼叫方式。

4.2 服務提供端程式碼

# Server相關配置
server:
  port: 18080

#Spring相關配置
spring:
  application:
    name: server1
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.2:8848

依賴:

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
     </dependency>
</dependencies>

啟動服務端:

@SpringBootApplication
@EnableDiscoveryClient
public class CloudServer1 {

    private static Logger logger = LoggerFactory.getLogger(CloudServer1.class);

    public static void main(String[] args) {
        System.setProperty("nacos.logging.default.config.enabled","false");
        logger.info("CloudServer1 begin to start...");
        SpringApplication.run(CloudServer1.class, args);
        logger.info("CloudServer1 start success...");
    }
}

4.3 服務呼叫端程式碼

step1:新增依賴

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-openfeign</artifactId>
     </dependency>
     <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
     </dependency>
</dependencies>

step2:新增配置

server:
  port: 9999

#Spring相關配置
spring:
  application:
    name: cloud-comsumer
  profiles:
    active: @profiles.active@
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.2:8848

step3:新增客戶端呼叫

@FeignClient(name = "server1")
public interface ServerConsumerClient {

    @GetMapping("/echo/chen")
    String echoChen();

    @GetMapping("/echo/zhao")
    String echoZhen();
}

step4:啟動應用

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class CloudApp {

    private static Logger logger = LoggerFactory.getLogger(CloudApp.class);

    public static void main(String[] args) {
        System.setProperty("nacos.logging.default.config.enabled","false");
        logger.info("app begin to start...");
        SpringApplication.run(CloudApp.class, args);
        logger.info("app start success...");
    }
}

Nacos 使用規範

  • 接入時必須填寫使用者密碼

原理性文章

  • Nacos 客戶端讀取配置、更新配置、刪除配置和監聽服務端配置變化的原理;

  • Nacos 各個日誌的功能;

  • 配置多個資料庫的原理;

  • Nacos 接入使用者時必須指定使用者密碼;

  • Nacos 使用者許可權管理。 --- https://www.cnblogs.com/yunqishequ/p/12720079.html 對服務發現有沒有影響

參考

相關文章