最強 Spring Cloud 註冊中心 Nacos,和艿艿來擼一波~

點擊上方“芋道源碼”,選擇“設爲星標

管她前浪,還是後浪?

能浪的浪,纔是好浪!

每天 8:55 更新文章,每天掉億點點頭髮...

源碼精品專欄

 

摘要: 原創出處 http://www.iocoder.cn/Spring-Cloud-Alibaba/Nacos-Discovery/ 「芋道源碼」歡迎轉載,保留摘要,謝謝!

  • 1. 概述

  • 2. 註冊中心原理

  • 3. 快速入門

  • 4. Nacos 概念詳解

  • 5. 更多的配置項信息

  • 6. 多環境配置

  • 7. 監控端點

  • 666. 彩蛋


本文在提供完整代碼示例,可見 https://github.com/YunaiV/SpringBoot-Labs 的 labx-01 目錄。

原創不易,給點個 Star 嘿,一起衝鴨!

1. 概述

本文我們來學習 Spring Cloud Alibaba 提供的 Spring Cloud Alibaba Nacos Discovery 組件,基於 Spring Cloud 的編程模型,接入 Nacos 作爲註冊中心,實現服務的註冊與發現。

服務註冊/發現: Nacos Discovery

服務發現是微服務架構體系中最關鍵的組件之一。如果嘗試着用手動的方式來給每一個客戶端來配置所有服務提供者的服務列表是一件非常困難的事,而且也不利於服務的動態擴縮容。

Nacos Discovery 可以幫助您將服務自動註冊到 Nacos 服務端並且能夠動態感知和刷新某個服務實例的服務列表。

除此之外,Nacos Discovery 也將服務實例自身的一些元數據信息-例如 host,port, 健康檢查URL,主頁等內容註冊到 Nacos。

在開始本文之前,胖友需要對 Nacos 進行簡單的學習。可以閱讀《Nacos 極簡入門》文章,將第一二小節看完,在本機搭建一個 Nacos 服務。

2. 註冊中心原理

在開始搭建 Nacos Discovery 的示例之前,我們先來簡單瞭解下注冊中心的原理。

在使用註冊中心時,一共有三種角色:服務提供者(Service Provider)、服務消費者(Service Consumer)、註冊中心(Registry)。

在一些文章中,服務提供者被稱爲 Server,服務消費者被稱爲 Client。胖友們知道即可。

三個角色交互如下圖所示:

① Provider:

  • 啓動時,向 Registry 註冊自己爲一個服務(Service)的實例(Instance)。

  • 同時,定期向 Registry 發送心跳,告訴自己還存活。

  • 關閉時,向 Registry 取消註冊

② Consumer:

  • 啓動時,向 Registry 訂閱使用到的服務,並緩存服務的實例列表在內存中。

  • 後續,Consumer 向對應服務的 Provider 發起調用時,從內存中的該服務的實例列表選擇一個,進行遠程調用。

  • 關閉時,向 Registry 取消訂閱

③ Registry:

  • Provider 超過一定時間未心跳時,從服務的實例列表移除。

  • 服務的實例列表發生變化(新增或者移除)時,通知訂閱該服務的 Consumer,從而讓 Consumer 能夠刷新本地緩存。

當然,不同的註冊中心可能在實現原理上會略有差異。例如說,Eureka 註冊中心,並不提供通知功能,而是 Eureka Client 自己定期輪詢,實現本地緩存的更新。

另外,Provider 和 Consumer 是角色上的定義,一個服務同時即可以是 Provider 也可以作爲 Consumer。例如說,優惠劵服務可以給訂單服務提供接口,同時又調用用戶服務提供的接口。

3. 快速入門

示例代碼對應倉庫:

  • 服務提供者:labx-01-sca-nacos-discovery-demo01-provider

  • 服務消費者:labx-01-sca-nacos-discovery-demo01-consumer

本小節,我們來搭建一個 Nacos Discovery 組件的快速入門示例。步驟如下:

  • 首先,搭建一個服務提供者 demo-provider ,註冊服務到 Nacos 中。

  • 然後,搭建一個服務消費者 demo-consumer,從 Nacos 獲取到 demo-provider 服務的實例列表,選擇其中一個示例,進行 HTTP 遠程調用。

3.1 搭建服務提供者

創建 labx-01-sca-nacos-discovery-demo01-provider 項目,作爲服務提供者 demo-provider。最終項目代碼如下圖所示:

3.1.1 引入依賴

pom.xml 文件中,主要引入 Spring Cloud Nacos Discovery 相關依賴。代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>labx-01</artifactId>
        <groupId>cn.iocoder.springboot.labs</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>labx-01-sca-nacos-discovery-demo01-provider</artifactId>

    <properties>
        <spring.boot.version>2.2.4.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version>
    </properties>

    <!--
        引入 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,進行依賴版本的管理,防止不兼容。
        在 https://dwz.cn/mcLIfNKt 文章中,Spring Cloud Alibaba 開發團隊推薦了三者的依賴關係
     -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- 引入 SpringMVC 相關依賴,並實現對其的自動配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 引入 Spring Cloud Alibaba Nacos Discovery 相關依賴,將 Nacos 作爲註冊中心,並實現對其的自動配置 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

</project>

友情提示:有點小長,不要慌~

<dependencyManagement /> 中,我們引入了 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,進行依賴版本的管理,防止不兼容。在《Spring Cloud 官方文檔 —— 版本說明》文檔中,推薦了三者的依賴關係。如下表格:

Spring Cloud VersionSpring Cloud Alibaba VersionSpring Boot Version
Spring Cloud Greenwich2.1.1.RELEASE2.1.X.RELEASE
Spring Cloud Finchley2.0.1.RELEASE2.0.X.RELEASE
Spring Cloud Edgware1.5.1.RELEASE1.5.X.RELEASE
  • 這裏,我們選擇了 Spring Cloud Alibaba 版本爲 2.2.0.RELEASE

  • 當前版版本下,我們使用的 Nacos 版本爲 1.1.4

引入 spring-cloud-starter-alibaba-nacos-discovery 依賴,將 Nacos 作爲註冊中心,並實現對它的自動配置。

3.1.2 配置文件

創建 application.yaml 配置文件,添加 Nacos Discovery 配置項。配置如下:

spring:
  application:
    name: demo-provider # Spring 應用名
  cloud:
    nacos:
      # Nacos 作爲註冊中心的配置項,對應 NacosDiscoveryProperties 配置類
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服務器地址
        service: ${spring.application.name} # 註冊到 Nacos 的服務名。默認值爲 ${spring.application.name}。

server:
  port: 18080 # 服務器端口。默認爲 8080

重點看 spring.cloud.nacos.discovery 配置項,它是 Nacos Discovery 配置項的前綴,對應 NacosDiscoveryProperties 配置項。

3.1.3 DemoProviderApplication

創建 DemoProviderApplication 類,創建應用啓動類,並提供 HTTP 接口。代碼如下:

@SpringBootApplication
@EnableDiscoveryClient
public class DemoProviderApplication {

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

    @RestController
    static class TestController {

        @GetMapping("/echo")
        public String echo(String name) {
            return "provider:" + name;
        }

    }

}

@SpringBootApplication 註解,被添加在類上,聲明這是一個 Spring Boot 應用。Spring Cloud 是構建在 Spring Boot 之上的,所以需要添加。

@EnableDiscoveryClient 註解,開啓 Spring Cloud 的註冊發現功能。不過從 Spring Cloud Edgware 版本開始,實際上已經不需要添加 @EnableDiscoveryClient 註解,只需要引入 Spring Cloud 註冊發現組件,就會自動開啓註冊發現的功能。例如說,我們這裏已經引入了 spring-cloud-starter-alibaba-nacos-discovery 依賴,就不用再添加 @EnableDiscoveryClient 註解了。

拓展小知識:在 Spring Cloud Common 項目中,定義了 DiscoveryClient 接口,作爲通用的發現客戶端,提供讀取服務和讀取服務列表的 API 方法。而想要集成到 Spring Cloud 體系的註冊中心的組件,需要提供對應的 DiscoveryClient 實現類。

例如說,Spring Cloud Alibaba Nacos Discovery 提供了 NacosDiscoveryClient 實現,Spring Cloud Netflix Eureka 提供了 EurekaDiscoveryClient 實現。

如此,所有需要使用到的地方,只需要獲取到 DiscoveryClient 客戶端,而無需關注具體實現,保證其通用性。

③ TestController 類,提供了 /echo 接口,返回 provider:${name} 結果。

3.1.4 簡單測試

① 通過 DemoProviderApplication 啓動服務提供者,IDEA 控制檯輸出日誌如:

// ... 省略其它日誌
2020-02-08 15:25:57.406  INFO 27805 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP demo-provider 10.171.1.115:18080 register finished
  • 服務 demo-provider 註冊到 Nacos 上的日誌。

② 打開 Nacos 控制檯,可以在服務列表看到服務 demo-provider。如下圖:

3.2 搭建服務消費者

創建 labx-01-sca-nacos-discovery-demo01-consumer 項目,作爲服務提供者 demo-consumer。最終項目代碼如下圖所示:

整個項目的代碼,和服務提供者是基本一致的,畢竟是示例代碼 ????

3.2.1 引入依賴

和「3.1.1 引入依賴」一樣,只是修改 Maven <artifactId />labx-01-sca-nacos-discovery-demo01-consumer,見 pom.xml 文件。

3.2.2 配置文件

創建 application.yaml 配置文件,添加相應配置項。配置如下:

spring:
  application:
    name: demo-consumer # Spring 應用名
  cloud:
    nacos:
      # Nacos 作爲註冊中心的配置項,對應 NacosDiscoveryProperties 配置類
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服務器地址

server:
  port: 28080 # 服務器端口。默認爲 8080

和「3.1.2 配置文件」基本一致,主要是將配置項目 spring.application.name 修改爲 demo-consumer

3.2.3 DemoConsumerApplication

創建 DemoConsumerApplication 類,創建應用啓動類,並提供一個調用服務提供者的 HTTP 接口。代碼如下:

@SpringBootApplication
// @EnableDiscoveryClient
public class DemoConsumerApplication {

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

    @Configuration
    public class RestTemplateConfiguration {

        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }

    }

    @RestController
    static class TestController {

        @Autowired
        private DiscoveryClient discoveryClient;
        @Autowired
        private RestTemplate restTemplate;
        @Autowired
        private LoadBalancerClient loadBalancerClient;

        @GetMapping("/hello")
        public String hello(String name) {
            // <1> 獲得服務 `demo-provider` 的一個實例
            ServiceInstance instance;
            if (true) {
                // 獲取服務 `demo-provider` 對應的實例列表
                List<ServiceInstance> instances = discoveryClient.getInstances("demo-provider");
                // 選擇第一個
                instance = instances.size() > 0 ? instances.get(0) : null;
            } else {
                instance = loadBalancerClient.choose("demo-provider");
            }
            // <2> 發起調用
            if (instance == null) {
                throw new IllegalStateException("獲取不到實例");
            }
            String targetUrl = instance.getUri() + "/echo?name=" + name;
            String response = restTemplate.getForObject(targetUrl, String.class);
            // 返回結果
            return "consumer:" + response;
        }

    }

}

@EnableDiscoveryClient 註解,因爲已經無需添加,所以我們進行了註釋,原因在上面已經解釋過。

② RestTemplateConfiguration 配置類,創建 RestTemplate Bean。RestTemplate 是 Spring 提供的 HTTP 調用模板工具類,可以方便我們稍後調用服務提供者的 HTTP API。

③ TestController 提供了 /hello 接口,用於調用服務提供者的 /demo 接口。代碼略微有幾行,我們來稍微解釋下哈。

discoveryClient 屬性,DiscoveryClient 對象,服務發現客戶端,上文我們已經介紹過。這裏我們注入的不是 Nacos Discovery 提供的 NacosDiscoveryClient,保證通用性。未來如果我們不使用 Nacos 作爲註冊中心,而是使用 Eureka 或則 Zookeeper 時,則無需改動這裏的代碼。

loadBalancerClient 屬性,LoadBalancerClient 對象,負載均衡客戶端。稍後我們會使用它,從 Nacos 獲取的服務 demo-provider 的實例列表中,選擇一個進行 HTTP 調用。

拓展小知識:在 Spring Cloud Common 項目中,定義了LoadBalancerClient 接口,作爲通用的負載均衡客戶端,提供從指定服務中選擇一個實例、對指定服務發起請求等 API 方法。而想要集成到 Spring Cloud 體系的負載均衡的組件,需要提供對應的 LoadBalancerClient 實現類。

例如說,Spring Cloud Netflix Ribbon 提供了 RibbonLoadBalancerClient 實現。

如此,所有需要使用到的地方,只需要獲取到 DiscoveryClient 客戶端,而無需關注具體實現,保證其通用性。???? 不過貌似 Spring Cloud 體系中,暫時只有 Ribbon 一個負載均衡組件。

當然,LoadBalancerClient 的服務的實例列表,是來自 DiscoveryClient 提供的。

/hello 接口,示例接口,對服務提供者發起一次 HTTP 調用。

  • <1> 處,獲得服務 demo-provider 的一個實例。這裏我們提供了兩種方式的代碼,分別基於 DiscoveryClient 和 LoadBalancerClient。

  • <2> 處,通過獲取到的服務實例 ServiceInstance 對象,拼接請求的目標 URL,之後使用 RestTemplate 發起 HTTP 調用。

3.2.4 簡單測試

① 通過 DemoConsumerApplication 啓動服務消費者,IDEA 控制檯輸出日誌如:

// ... 省略其它日誌
2020-02-08 18:05:35.810  INFO 35047 --- [           main] c.a.c.n.registry.NacosServiceRegistry    : nacos registry, DEFAULT_GROUP demo-consumer 10.171.1.115:28080 register finished
  • 服務 demo-consumer 註冊到 Nacos 上的日誌。

注意,服務消費者和服務提供是一種角色的概念,本質都是一種服務,都是可以註冊自己到註冊中心的。

② 打開 Nacos 控制檯,可以在服務列表看到服務 demo-consumer。如下圖:

③ 訪問服務消費者的 http://127.0.0.1:28080/hello?name=yudaoyuanma 接口,返回結果爲 "consumer:provider:yudaoyuanma"。說明,調用遠程的服務提供者成功。

④ 打開 Nacos 控制檯,可以在訂閱者列表看到訂閱關係。如下圖:

⑤ 關閉服務提供者後,再次訪問 http://127.0.0.1:28080/hello?name=yudaoyuanma 接口,返回結果爲報錯提示 "獲取不到實例",說明我們本地緩存的服務 demo-provider 的實例列表已刷新,沒有任何實例。

???? 這裏我們並沒有演示啓動多個服務提供者的測試,胖友可以自己嘗試下喲。

4. Nacos 概念詳解

友情提示:本小節的內容,基於如下兩篇文檔梳理,推薦胖友後續也看看:

  • 《Nacos 官方文檔 —— 概念》

  • 《Nacos 官方文檔 —— 架構》

4.1 數據模型

Nacos 數據模型 Key 由三元組唯一確認。如下圖所示:

  • 作爲註冊中心時,Namespace + Group + Service

  • 作爲配置中心時,Namespace + Group + DataId

我們來看看 Namespace、Group、Service 的概念。

4.1.1 Namespace 命名空間

用於進行租戶粒度的配置隔離。默認爲 public(公共命名空間)。

不同的命名空間下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用場景之一是不同環境的配置的區分隔離,例如開發測試環境和生產環境的資源(如配置、服務)隔離等。

稍後在「6. 多環境配置」小節中,我們會通過 Namespace 隔離不同環境的服務。

4.1.2 Group 服務分組

不同的服務可以歸類到同一分組。默認爲 DEFAULT_GROUP(默認分組)。

4.1.3 Service 服務

例如說,用戶服務、訂單服務、商品服務等等。

4.2 服務領域模型

Service 可以進一步細拆服務領域模型,如下圖:

我們來看看圖中的每個“節點”的概念。

4.2.1 Instance 實例

提供一個或多個服務的具有可訪問網絡地址(IP:Port)的進程。

我們以「3.1 搭建服務提供者」小節來舉例子:

  • 如果我們啓動一個 JVM 進程,就是服務 demo-provider 下的一個實例。

  • 如果我們啓動多個 JVM 進程,就是服務 demo-provider 下的多個實例。

4.2.2 Cluster 集羣

同一個服務下的所有服務實例組成一個默認集羣(Default)。集羣可以被進一步按需求劃分,劃分的單位可以是虛擬集羣。

例如說,我們將服務部署在多個機房之中,每個機房可以創建爲一個虛擬集羣。每個服務在註冊到 Nacos 時,設置所在機房的虛擬集羣。這樣,服務在調用其它服務時,可以通過虛擬集羣,優先調用本機房的服務。如此,在提升服務的可用性的同時,保證了性能。

4.2.3 Metadata 元數據

Nacos 元數據(如配置和服務)描述信息,如服務版本、權重、容災策略、負載均衡策略、鑑權配置、各種自定義標籤 (label)。

從作用範圍來看,分爲服務級別的元信息、集羣的元信息及實例的元信息。如下圖:

FROM 《Dubbo 官方文檔 —— 多版本》

以 Nacos 元數據的服務版本舉例子。當一個接口實現,出現不兼容升級時,可以用版本號過渡,版本號不同的服務相互間不引用。

可以按照以下的步驟進行版本遷移:

  1. 在低壓力時間段,先升級一半提供者爲新版本

  2. 再將所有消費者升級爲新版本

  3. 然後將剩下的一半提供者升級爲新版本

FROM 《Dubbo 官方文檔 —— 令牌驗證》

再次 Nacos 元數據的鑑權配置舉例子。通過令牌驗證在註冊中心控制權限,以決定要不要下發令牌給消費者,可以防止消費者繞過註冊中心訪問提供者。另外,通過註冊中心可靈活改變授權方式,而不需修改或升級提供者。

令牌驗證

4.2.4 Health Check 健康檢查

以指定方式檢查服務下掛載的實例的健康度,從而確認該實例是否能提供服務。根據檢查結果,實例會被判斷爲健康或不健康。

對服務發起解析請求時,不健康的實例不會返回給客戶端。

健康保護閾值

爲了防止因過多實例不健康導致流量全部流向健康實例,繼而造成流量壓力把健康實例實例壓垮並形成雪崩效應,應將健康保護閾值定義爲一個 0 到 1 之間的浮點數。

當域名健康實例佔總服務實例的比例小於該值時,無論實例是否健康,都會將這個實例返回給客戶端。這樣做雖然損失了一部分流量,但是保證了集羣的剩餘健康實例能正常工作。

4.3 小結

爲了讓胖友更好理解,我們把數據模型和服務領域模型整理如下圖所示:

5. 更多的配置項信息

在「3. 快速入門」小節中,我們爲了快速入門,只使用了 Nacos Discovery Starter 兩個配置項。實際上,Nacos Discovery Starter 提供的配置項挺多的,我們參考文檔將配置項一起梳理下。

Nacos 服務器相關

配置項Key說明
服務端地址spring.cloud.nacos.discovery.server-addrNacos Server 啓動監聽的ip地址和端口
AccessKeyspring.cloud.nacos.discovery.access-key當要上阿里雲時,阿里雲上面的一個雲賬號名
SecretKeyspring.cloud.nacos.discovery.secret-key當要上阿里雲時,阿里雲上面的一個雲賬號密碼

服務相關

配置項Key說明
命名空間spring.cloud.nacos.discovery.namespace常用場景之一是不同環境的註冊的區分隔離,例如開發測試環境和生產環境的資源(如配置、服務)隔離等
服務分組spring.cloud.nacos.discovery.group不同的服務可以歸類到同一分組。默認爲 DEFAULT_GROUP
服務名spring.cloud.nacos.discovery.service註冊的服務名。默認爲 ${spring.application.name}
集羣spring.cloud.nacos.discovery.cluster-nameNacos 集羣名稱。默認爲 DEFAULT
權重spring.cloud.nacos.discovery.weight取值範圍 1 到 100,數值越大,權重越大。默認爲 1
Metadataspring.cloud.nacos.discovery.metadata使用Map格式配置,用戶可以根據自己的需要自定義一些和服務相關的元數據信息
是否開啓Nacos Watchspring.cloud.nacos.discovery.watch.enabled可以設置成 false 來關閉 watch。默認爲 true

網絡相關

配置項Key說明
網卡名spring.cloud.nacos.discovery.network-interface當  IP未配置時,註冊的 IP 爲此網卡所對應的 IP 地址,如果此項也未配置,則默認取第一塊網卡的地址
註冊的IP地址spring.cloud.nacos.discovery.ip優先級最高
註冊的端口spring.cloud.nacos.discovery.port默認情況下不用配置,會自動探測。默認爲 -1

其它相關

配置項Key說明
是否集成 Ribbonribbon.nacos.enabled一般都設置成true 即可。默認爲 true
日誌文件名spring.cloud.nacos.discovery.log-name
接入點spring.cloud.nacos.discovery.endpoint地域的某個服務的入口域名,通過此域名可以動態地拿到服務端地址

6. 多環境配置

示例代碼對應倉庫:

  • 服務提供者:labx-01-sca-nacos-discovery-demo02-provider

  • 服務消費者:labx-01-sca-nacos-discovery-demo02-consumer

同一個服務,我們會部署到開發、測試、預發佈、生產等環境中,那麼我們需要在項目中,添加不同環境的 Nacos 配置。一般情況下,開發和測試使用同一個 Nacos,預發佈和生產使用另一個 Nacos。那麼針對相同的 Nacos,我們怎麼實現不同環境的隔離呢?

實際上,Nacos 開發者已經告訴我們如何實現了,通過 Nacos Namespace 命名空間。文檔說明如下:

FROM 《Nacos 文檔 —— Nacos 概念》

命名空間,用於進行租戶粒度的配置隔離。不同的命名空間下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用場景之一是不同環境的配置的區分隔離,例如開發測試環境和生產環境的資源(如配置、服務)隔離等。

下面,我們來搭建一個多環境配置的示例。步驟如下:

  • 首先,我們會在 Nacos 中創建開發環境使用的 Namespace 爲 dev,測試環境使用的 Namespace 爲 uat

  • 然後,搭建一個服務提供者 demo-provider,使用開發環境配置,註冊服務到 Nacos 的 dev Namespace 下。

  • 之後,搭建一個服務消費者 demo-consumer,調用服務提供者 demo-provider 提供的 HTTP 接口。

    • 先使用開發環境配置,因爲服務 demo-provider 在 Nacos dev Namespace 下注冊,所以調用它成功

    • 後使用測試環境配置,因爲服務 demo-provider 在 Nacos uat Namespace 下注冊,所以調用它失敗

友情提示:在 Spring Boot(Spring Cloud)項目中,可以使用 Profiles 機制,基於 spring.profiles.active 配置項,實現不同環境讀取不同的配置文件。

不瞭解的胖友,可以看看《芋道 Spring Boot 配置文件入門》的「6. 多環境配置」小節。

6.1 創建 Nacos 命名空間

① 打開 Nacos UI 界面的「命名空間」菜單,進入「命名空間」功能。如下圖所示:

② 點擊列表右上角的「新建命名空間」按鈕,彈出「新建命名空間」窗口,創建一個 dev 命名空間。輸入如下內容,並點擊「確定」按鈕,完成創建。如下圖所示:

③ 重複該操作,繼續創建一個 uat 命名空間。最終 devuat 信息如下圖:

6.2 搭建服務提供者

從「3.1 搭建服務提供者」小節的 labx-01-sca-nacos-discovery-demo01-provider 項目,複製出 labx-01-sca-nacos-discovery-demo02-provider 項目。然後在其上進行修改,方便搭建~

6.2.1 配置文件

修改 application.yaml 配置文件,將 Nacos Discovery 配置項刪除,稍後添加在不同環境的配置文件中。配置如下:

spring:
  application:
    name: demo-provider # Spring 應用名

server:
  port: 18080 # 服務器端口。默認爲 8080

創建開發環境使用的 application-dev.yaml 配置文件,增加 Namespace 爲 dev 的 Nacos Discovery 配置項。配置如下:

spring:
  cloud:
    nacos:
      # Nacos 作爲註冊中心的配置項,對應 NacosDiscoveryProperties 配置類
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服務器地址
        namespace: 14226a0d-799f-424d-8905-162f6a8bf409 # Nacos 命名空間 dev 的編號

創建測試環境使用的 application-uat.yaml 配置文件,增加 Namespace 爲 uat 的 Nacos Discovery 配置項。配置如下:

spring:
  cloud:
    nacos:
      # Nacos 作爲註冊中心的配置項,對應 NacosDiscoveryProperties 配置類
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服務器地址
        namespace: bc8c8c2d-bd85-42bb-ada3-1a8f940ceb20 # Nacos 命名空間 uat 的編號

6.2.2 簡單測試

下面,我們使用命令行參數進行 --spring.profiles.active 配置項,實現不同環境,讀取不同配置文件。

① 先配置 --spring.profiles.activedev,設置 DemoProviderApplication 讀取 application-dev.yaml 配置文件。如下圖所示:

之後通過 DemoProviderApplication 啓動服務提供者。

② 打開 Nacos 控制檯,可以在服務列表看到服務 demo-provider 註冊在命名空間 dev 下。如下圖:

6.3 搭建服務消費者

從「3.2 搭建服務消費者」小節的 labx-01-sca-nacos-discovery-demo01-consumer 項目,複製出 labx-01-sca-nacos-discovery-demo02-consumer 項目。然後在其上進行修改,方便搭建~

6.3.1 配置文件

友情提示:和「6.2.1 配置文件」小節的內容是基本一致的,重複嘮叨一遍。

修改 application.yaml 配置文件,將 Nacos Discovery 配置項刪除,稍後添加在不同環境的配置文件中。配置如下:

spring:
  application:
    name: demo-consumer # Spring 應用名

server:
  port: 28080 # 服務器端口。默認爲 8080

創建開發環境使用的 application-dev.yaml 配置文件,增加 Namespace 爲 dev 的 Nacos Discovery 配置項。配置如下:

spring:
  cloud:
    nacos:
      # Nacos 作爲註冊中心的配置項,對應 NacosDiscoveryProperties 配置類
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服務器地址
        namespace: 14226a0d-799f-424d-8905-162f6a8bf409 # Nacos 命名空間 dev 的編號

創建測試環境使用的 application-uat.yaml 配置文件,增加 Namespace 爲 uat 的 Nacos Discovery 配置項。配置如下:

spring:
  cloud:
    nacos:
      # Nacos 作爲註冊中心的配置項,對應 NacosDiscoveryProperties 配置類
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服務器地址
        namespace: bc8c8c2d-bd85-42bb-ada3-1a8f940ceb20 # Nacos 命名空間 uat 的編號

6.2.3 簡單測試

下面,我們使用命令行參數進行 --spring.profiles.active 配置項,實現不同環境,讀取不同配置文件。

① 先配置 --spring.profiles.activedev,設置 DemoConsumerApplication 讀取 application-dev.yaml 配置文件。如下圖所示:

之後通過 DemoConsumerApplication 啓動服務消費者。

訪問服務消費者的 http://127.0.0.1:28080/hello?name=yudaoyuanma 接口,返回結果爲 "consumer:provider:yudaoyuanma"。說明,調用遠程的服務提供者【成功】。

② 再配置 --spring.profiles.activeuat,設置 DemoConsumerApplication 讀取 application-uat.yaml 配置文件。如下圖所示:

之後通過 DemoConsumerApplication 啓動服務消費者。

訪問服務消費者的 http://127.0.0.1:28080/hello?name=yudaoyuanma 接口,返回結果爲 報錯提示 "獲取不到實例"。說明,調用遠程的服務提供者【失敗】。

原因是,雖然說服務 demo-provider 已經啓動,因爲其註冊在 Nacos 的 Namespace 爲 dev,這就導致第 ① 步啓動的服務 demo-consumer 可以調用到該服務,而第② 步啓動的服務 demo-consumer 無法調用到該服務。

即,我們可以通過 Nacos 的 Namespace 實現不同環境下的服務隔離。未來,在開源版本 Nacos 權限完善之後,每個 Namespace 提供不同的 AccessKey、SecretKey,保證只有知道賬號密碼的服務,才能連到對應的 Namespace,進一步提升安全性。

7. 監控端點

示例代碼對應倉庫:

  • 服務提供者:labx-01-sca-nacos-discovery-demo01-provider

  • 服務消費者:labx-01-sca-nacos-discovery-demo03-consumer

Nacos Discovery 基於 Spring Boot Actuator,提供了自定義監控端點 nacos-discovery,獲取 Nacos Discovery 配置項,和訂閱的服務信息。

同時,Nacos Discovery 拓展了 Spring Boot Actuator 內置的 health 端點,通過自定義的 NacosDiscoveryHealthIndicator,獲取和 Nacos 服務器的連接狀態。

友情提示:對 Spring Boot Actuator 不瞭解的胖友,可以後續閱讀《芋道 Spring Boot 監控端點 Actuator 入門》文章。

下面,我們來搭建一個 Nacos Discovery 監控端點的示例。步驟如下:

  • 首先,搭建一個服務提供者 demo-provider ,註冊服務到 Nacos 中。

  • 然後,搭建一個服務消費者 demo-consumer,調用服務提供者 demo-provider 提供的 HTTP 接口。同時,配置開啓服務消費者的 Nacos Discovery 監控端點。

  • 最後,訪問服務消費者的 Nacos Discovery 監控端點,查看下返回的監控數據。

7.1 搭建服務提供者

直接複用「3.1 搭建服務提供者」小節的 labx-01-sca-nacos-discovery-demo01-provider 項目即可。

因爲 labx-01-sca-nacos-discovery-demo01-provider 項目沒有從 Nacos 訂閱任何服務,無法完整看到 nacos-discovery 端點的完整效果,所以我們暫時不配置該項目的 Nacos Discovery 監控端點。

不過實際項目中,配置下開啓 Nacos Discovery 監控端點 還是可以的,至少可以看到 Nacos Discovery 配置項。

7.2 搭建服務消費者

從「3.2 搭建服務消費者」小節的 labx-01-sca-nacos-discovery-demo01-consumer 項目,複製出 labx-01-sca-nacos-discovery-demo03-consumer 項目。然後在其上進行修改,方便搭建~

7.2.1 引入依賴

pom.xml 文件中,額外引入 Spring Boot Actuator 相關依賴。代碼如下:

<!-- 實現對 Actuator 的自動化配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

7.2.2 配置文件

修改 application.yaml 配置文件,增加 Spring Boot Actuator 配置項。配置如下:

management:
  endpoints:
    web:
      exposure:
        include: '*' # 需要開放的端點。默認值只打開 health 和 info 兩個端點。通過設置 * ,可以開放所有端點。
  endpoint:
    # Health 端點配置項,對應 HealthProperties 配置類
    health:
      enabled: true # 是否開啓。默認爲 true 開啓。
      show-details: ALWAYS # 何時顯示完整的健康信息。默認爲 NEVER 都不展示。可選 WHEN_AUTHORIZED 當經過授權的用戶;可選 ALWAYS 總是展示。

每個配置項的作用,胖友看下艿艿添加的註釋。如果還不理解的話,後續看下《芋道 Spring Boot 監控端點 Actuator 入門》文章。

7.3 簡單測試

① 通過 DemoProviderApplication 啓動服務提供者,通過 DemoConsumerApplication 啓動服務消費者。

之後,訪問服務消費者的 http://127.0.0.1:28080/hello?name=yudaoyuanma 接口,返回結果爲 "consumer:provider:yudaoyuanma"。a說明,調用遠程的服務提供者成功。

② 訪問服務消費者的 nacos-discovery 監控端點 http://127.0.0.1:28080/actuator/nacos-discovery,返回結果如下圖:

理論來說,"subscribe" 字段應該返回訂閱的服務 demo-provider 的信息,結果這裏返回的是空。後來翻看了下源碼,是需要主動向 Nacos EventDispatcher 註冊 EventListener 纔可以。咳咳咳,感覺這個設定有點神奇~

③ 訪問服務消費者的 health 監控端點 http://127.0.0.1:28080/actuator/health,返回結果如下圖:

666. 彩蛋

至此,我們已經完成 Spring Cloud Alibaba Nacos Discovery 的學習。如下是 Nacos 相關的官方文檔:

  • 《Nacos 官方文檔》

  • 《Spring Cloud Alibaba 官方文檔 —— Nacos Discovery》

  • 《Spring Cloud Alibaba 官方示例 —— Nacos Discovery》

另外,想要在 Spring Boot 項目中使用 Nacos 作爲註冊中心的胖友,可以閱讀《芋道 Spring Boot 註冊中心 Nacos 入門》文章。



歡迎加入我的知識星球,一起探討架構,交流源碼。加入方式,長按下方二維碼噢

已在知識星球更新源碼解析如下:

最近更新《芋道 SpringBoot 2.X 入門》系列,已經 20 餘篇,覆蓋了 MyBatis、Redis、MongoDB、ES、分庫分表、讀寫分離、SpringMVC、Webflux、權限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能測試等等內容。

提供近 3W 行代碼的 SpringBoot 示例,以及超 4W 行代碼的電商微服務項目。

獲取方式:點“在看”,關注公衆號並回復 666 領取,更多內容陸續奉上。

兄弟,一口,點個????

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章