Nacos


一、什么是Nacos

  英文全稱Dynamic Naming and Configuration Service,Na為naming/nameServer即注冊中心,co為configuration即注冊中心,service是指該注冊/配置中心都是以服務為核心

  Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理

二、Nacos原理

  

  Nacos注冊中心分為server與client,server采用Java編寫,為client提供注冊發現服務與配置服務。而client可以用多語言實現,client與微服務嵌套在一起,nacos提供sdk和openApi,如果沒有sdk也可以根據openApi手動寫服務注冊與發現和配置拉取的邏輯

  

  Nacos服務領域模型主要分為命名空間、集群、服務。在下圖的分級存儲模型可以看到,在服務級別,保存了健康檢查開關、元數據、路由機制、保護閾值等設置,而集群保存了健康檢查模式、元數據、同步機制等數據,實例保存了該實例的ip、端口、權重、健康檢查狀態、下線狀態、元數據、響應時間

  

注冊中心原理

  

  服務注冊方法:以Java nacos client v1.0.1 為例子,服務注冊的策略的是每5秒向nacos server發送一次心跳,心跳帶上了服務名,服務ip,服務端口等信息。同時 nacos server也會向client 主動發起健康檢查,支持tcp/http檢查。如果15秒內無心跳且健康檢查失敗則認為實例不健康,如果30秒內健康檢查失敗則剔除實例

配置中心原理

  

三、 Nacos使用方法

創建命名空間

  不同的命名空間邏輯上是隔離的,不特殊設置的情況下,服務不會跨命名空間請求,命名空間主要的作用是區分服務使用的范圍,比如開發、測試、生產、灰度可以分別設置四個命名空間來互相隔離  

   如圖所示,在控制台的 服務管理-命名空間-新建命名空間按鈕可以創建新的命名空間,命名空間創建后,會在列表顯示命名空間ID,這個ID后面會用在服務的配置文件中

在服務上配置注冊、配置中心

  以springcloud為例,首先用maven導入nacos clinet的依賴:

     <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>0.2.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
     

  先導入springcloud的alibaba-nacos-config和alibaba-nacos-discovery兩個依賴,這兩個依賴是用於nacos clinet與cloud結合的工具,0.2.x對應springboot 2.x.x ,0.1.x對應springboot 1.x.x。這兩個組件可以和各種版本的nacos-client結合。把其中的nacos-clinet依賴給排除,引入想要引入的nacosclinet版本,如下:

   <!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.0.1</version>
        </dependency>

  在bootstrap.properties上添加配置中心的配置,如果springboot啟動類沒有@EnableDiscover注解則加上,完成如上更改,即可使用Nacos注冊/配置服務

spring.cloud.nacos.discovery.server-addr=nacos.e.189.cn:80
spring.cloud.nacos.discovery.namespace=命名空間id

通過配置更改動態刷新參數

  普通application參數在配置中心直接配置皆可,如果需要可以動態刷新的配置,需要在相應類上加上@RefreshScope注解,示例如下,當在nacos配置中心更改配置后,方法getId的值也會刷新

@RefreshScope
public class IdEntity {
    @Value("${id}")
    private int id;
    public int getId(){
        return this.id;
    }
}

配置中心參數修改/設置

  如下兩張圖:在nacos控制台的 配置管理-配置列表中頂部選擇相應的命名空間,點擊列表右上角的加號新增配置,Data ID 為 項目名-{spring.profiles.active}.properties,Group如果在bootstrap.properties中不指定則填默認的DEFAULT_GROUP,描述寫該配置的描述,配置內容填寫Properties格式或者Yaml格式
  

 

nacos其他功能使用與介紹

控制台手動上下線實例

  在控制台的服務管理-服務列表選擇一個服務點擊詳情,在下方的集群列表可以看到有上線/下線按鈕,點擊即可以對該實例執行上線/下線操作,下線后的實例不會被請求

配置實例權重

  可以通過手動配置權重來控制流量,當一個集群內兩個實例,權重越高,到達該實例的請求比例越多,權重的初始值是1

  

配置保護閾值

  保護閾值的范圍是0~1
  服務的健康比例=服務的健康實例/總實例個數
  當服務健康比例<=保護閾值時候,無論實例健不健康都會返回給調用方
  當服務健康比例>保護閾值的時候,只會返回健康實例給調用方
  在服務管理-服務列表選擇一個服務點擊詳情可以配置

四 Nacos作為注冊中心

  我們創建一個springcloud父工程,只包含web依賴。然后基於該父工程,分別創建服務提供者Provider和消費者Consumer工程。

服務提供者Provider

  需要的依賴如下:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.1</version>
</dependency>

  配置文件如下:

server:
  port: 8091
spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      server-addr: localhost:8848

  創建一個controller來模擬Provider對外提供服務:

@RestController
public class HelloController {

    @GetMapping("/getHello")
    public String getHello(){
        return "hello from nacos provider!";
    }

}

  到此,我們服務提供者就創建好了,在localhost:8091端口等待被調用提供服務

服務消費者Consumer

  需要的依賴如下:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.1</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>3.0.3</version>
</dependency>

  配置文件如下:

server:
  port: 8092
spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      server-addr: localhost:8848

  創建一個Controller類,對外提供調用的接口,然后在Controller中通過OpenFeign轉發調用請求給到Provider

@RestController
public class HelloController {

    @Autowired
    private FeignService feignService;

    @GetMapping("/getHello")
    public String getHello(){
        return feignService.getHello();
    }

}
@FeignClient("nacos-provider")
public interface FeignService {

    @GetMapping("/getHello")
    String getHello();

}

  如上Service表示需要請求注冊中心中服務名稱為nacos-provider的/getHello接口。最后,我們需要在啟動類上加上啟動注解

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class DiscoveryConsumerApplication {

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

}

  到此,消費者Consumer也創建好了,在localhost:8092提供調用服務。我們訪問Consumer的/getHello接口,獲得的返回內容為:

  hello from nacos provider! 

五 Nacos作為配置中心

入門案例

  首先我們需要引入必要的依賴包:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2021.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

  我們在啟動配置文件bootstrap.properties中配置如下的內容:

spring.application.name=nacos-provider
spring.cloud.nacos.server-addr=127.0.0.1:8848

  然后我們創建一個Controller就可以演示從遠端獲取配置內容了:

@RefreshScope
@RestController
public class ConfigController {

    @Value("${provider.name}")
    private String providerName;

    @GetMapping("/getDevConfig")
    public String getDevConfig(){
        return this.providerName;
    }

}

  代碼層面的示例都已經寫好了,我們在遠端nacos服務端,切換到配置管理的配置列表界面,需要點擊+號新建一個:

  • DataID,該字段的取名是有規則的,一般而言分為三個部分,{1}-{2}.{3},其中第一部分應該和剛才本地bootstrap.properties中配置的spring.application.name完全一樣;第二部分表示生效的環境名稱,比如dev、stg等;第三部分表示配置文件后綴,只支持properties或者yaml類型。在這里,我們的值應該為nacos-provider.properties
  • Group,這里先設置默認的DEFAULT_GROUP即可;
  • 配置內容,把需要保存在遠端Nacos的配置內容寫在里面即可,這里為provider.name=nacos123

  配置點擊發布后,我們啟動本地的nacos-provider服務,訪問Controller,就會發現讀取到了nacos123的配置內容。

配置文件的環境區分

  在實際使用時,我們一般都是區分dev、stg、prd三套環境來維護各個環境的配置文件內容的。在這樣的情況下,我們的應用程序如何讀取不同環境下的配置內容呢

通過profile區分

  首先我們在Nacos配置中心再增加兩個DataID,分別如下:

# nacos-provider-dev.properties
# DEFAULT_GROUP
provider.name=nacos-dev
# nacos-provider-stg.properties
# DEFAULT_GROUP
provider.name=nacos-stg

  為了讓這兩個配置文件生效,我們在本地應用端的bootstrap.properties中指定生效配置文件的環境名稱即可:

spring.application.name=nacos-provider
spring.cloud.nacos.server-addr=127.0.0.1:8848
spring.profiles.active=dev
# spring.profiles.active=stg

  再重啟我們的應用,就能讀取到各自環境的配置文件了

通過namespace區分

  默認我們會到public這個命名空間下去讀取配置文件,此時我們新建兩個命名空間,分別命名為dev和stg,然后將public命名空間下的nacos-provider.properties克隆到dev和stg命名空間下,並修改provider.name的配置內容:

# namespace dev
provider.name=nacos-dev-123
# namespace stg
provider.name=nacos-stg-123

  我們在本地的應用中增加一個配置項,表明想要引用的namespace:

spring.cloud.nacos.config.namespace=0a6be74a-426e-45eb-8531-6d7230f26af6

  然后重啟應用,就能讀取到對應namespace下面的配置內容了

加載多配置文件

  默認情況下,本地應用會去nacos服務端讀取對應namespace下面的以應用名稱開頭的配置文件,在本例子中就是nacos-provider.properties,因為我們本地應用配置的spring.application.name=nacos-provider,在實際開發中,往往會有多個配置文件,那么如何同時加載多個配置文件中的配置內容呢?

  首先,我們在public命名空間下再新建兩個配置文件:

# redis.properties
redis.server=127.0.0.1
# mq.properties
mq.nameserver=localhost

  同時,我們需要在本地項目的bootstrap.properties配置文件中增加如下的配置內容:

spring.cloud.nacos.config.ext-config[0].data-id=redis.properties
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[0].data-id=mq.properties
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[0].refresh=true

  對應的yml配置形式為:

spring:
  cloud:
    nacos:
      config:
        extension-configs:
          - refresh: true
            group: DEFAULT_GROUP
            data-id: redis.properties
          - refresh: true
            group: DEFAULT_GROUP
            data-id: mq.properties

  然后,修改我們的controller,引用nacos服務器上的不同配置文件里面的配置項:

@RefreshScope
@RestController
public class ConfigController {

    @Value("${provider.name}")
    private String providerName;
    @Value("${redis.server}")
    private String redisServer;
    @Value("${mq.nameserver}")
    private String mqServer;

    @GetMapping("/getDevConfig")
    public String getDevConfig() {
        return this.providerName + "/" + this.redisServer + "/" + this.mqServer;
    }

}

  重啟應用后,就能成功訪問不同配置文件里面的配置項了。

配置文件的分組區分

  如上我們注意到,分組Group一直都是DEFAULT_GROUP,其實我們可以在不同的Group里面創建相同名稱的配置文件。比如在微服務環境中,多個微服務組件都有redis.properties的配置文件,那么如何區分哪個微服務該使用哪個Group下面的配置文件呢,其實也很簡單,只要在配置文件中指定Group即可。

本實例比較簡單,就不演示了,其實對於同一個應用也可以讀取不同Group下面的配置文件配置內容,我們完全也可以用Group來作為dev、stg和prd的區分。

  總之,Nacos為我們提供了三個維度來做區分,即profile、namespace和Group,開發者可以靈活應用來做自己想要的區分。

共享配置

  很多時候,多個微服務中有相同的配置內容,比如大家連結的是同一個redis服務,同一個mq服務,那么就需要在各自的配置文件中都寫上相同的配置內容,顯得比較繁瑣,我們完全可以將這些共同的配置內容抽取出來,形成另一個配置文件,然后大家共享它。

  比如,我們在public命名空間下新建DEFAULT_GROUP的配置文件share.properties

provider.share=share123

  然后本地配置文件中新增如下配置內容:

# 如果有多個共享配置文件,相互之間用逗號分隔即可
spring.cloud.nacos.config.shared_dataids: share.properties
spring.cloud.nacos.config.refreshable-dataids: share.properties

  然后在Controller中增加共享配置的讀取內容,此處就省略了,重啟應用就可以生效了。

  注意,如果共享配置不是DEFAULT_GROUP下面的,就不能使用如上的方式,而是采用2.3節中講述的方式

配置內容的優先級

  有些時候,我們在加載的配置文件中都配置了同一個配置項的值,而且相互之間都不相同,那么本地應用最終以哪個配置文件中的內容為准呢

  • A:使用spring.cloud.nacos.config.prefixspring.cloud.nacos.config.file-extensionspring.cloud.nacos.config.group這幾個參數拼接出來的配置文件;
  • B:使用2.3節中extension-configs指定的配置間件;
  • C:使用2.5節中共享配置指定的配置文件;
  • D:本地配置的配置內容;

  優先級順序為:D>A>B>C


免責聲明!

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



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