1. 程式人生 > 實用技巧 >【SpringCloud】SpringCloud Alibaba Nacos服務註冊和配置中心

【SpringCloud】SpringCloud Alibaba Nacos服務註冊和配置中心

SpringCloud Alibaba Nacos服務註冊和配置中心

Nacos簡介

為什麼叫Nacos

前四個字母為Nameing和Configuration的前兩個字母,最後的s為Service

是什麼

  • 一個更易於構建原生應用的動態服務發現、配置管理和服務管理平臺
  • Nacos:Dynamic Naming and Configuration Service
  • Nacos就是註冊中心+配置中心的組合

    等價於:Nacos=Eureka+Config+Bus

能幹嘛

  • 替代Eureka做服務註冊中心
  • 替代Config做服務配置中心

去哪下

https://github.com/alibaba/Nacos

官網文件

  • https://nacos.io/zh-cn/
  • https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_discovery

各種註冊中心對比

服務註冊與發現框架 CAP模型 控制檯管理 社群活躍度
Eureka AP 支援 低(2.x版本閉源)
Zookeeper CP 不支援
Consul CP 支援
Nacos AP 支援

據說Nacos在阿里巴巴內部有超過10萬的例項執行,已經過了類似雙十一等各種大型流量的考驗

安裝並執行Nacos

  • 本地Java8+Maven環境已經ok
  • 先從官網下載Nacos
  • 解壓安裝包,直接執行bin目錄下的startup.cmd
  • 命令執行成功後直接訪問http://localhost:8848/nacos

    預設使用者名稱密碼都是nacos

  • 結果頁面

Nacos作為服務註冊中心演示

官方文件

https://spring.io/projects/spring-cloud-alibaba

詳細說明文件
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_start_a_provider_application

基於Nacos的服務提供者

新建module

cloudalibaba-provider-payment9001

POM

父POM

<!--Spring cloud alibaba 2.1.0.RELEASE-->
<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>

本模組POM

<dependencies>
    <!-- SpringCloud ailibaba nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-actuator</artifactId>
    </dependency>
    <!--熱部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

YML

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'

主啟動

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9001 {

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

業務類

@RestController
public class PaymentController {

    @Value("${server.port}")
    private String serverPort;
    
    @GetMapping(value = "/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id) {
        return "Hello Nacos Discovery: " + serverPort + "\t id: " + id;
    }
}

測試

http://localhost:9001/payment/nacos/31

nacos控制檯

nacos服務註冊中心+服務提供者9001都ok了

為了下一章演示nacos叢集,參考9001新建9002

這裡如果名字取錯了還暴力刪除導致建立的工程沒有source標誌的,那是因為父工程的.idea檔案沒有更新,記得關掉專案刪除.idea,再重新匯入專案即可

cloudalibaba-provider-payment9002

取巧的方法是,直接拷貝虛擬埠對映(不建議,自己玩玩可以,因為還是同一個模組)

基於Nacos的服務消費者

新建Module

cloudalibaba-consumer-nacos-order83

POM

<dependencies>
    <!-- SpringCloud ailibaba nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency><!-- 引用自己定義的api通用包,可以使用Payment支付Entity -->
        <groupId>com.eiletxie.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--監控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--熱部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

為什麼Nacos支援負載均衡


nacos內建了 ribbon

YML

server:
  port: 83

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

#消費者將去訪問的微服務名稱(註冊成功進nacos的微服務提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

主啟動

@SpringBootApplication
@EnableDiscoveryClient
public class OrderNacosMain83 {

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

業務類

ApplicationContextConfig

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

OrderNacosController

@RestController
@Slf4j
public class OrderNacosController {

    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String serverURL;

    @GetMapping(value = "/consumer/payment/nacos/{id}")
    public String paymentInfo(@PathVariable("id") Integer id) {
        return restTemplate.getForObject(serverURL + "/payment/nacos/" + id,String.class);
    }
}

測試

http://localhost:83/consumer/payment/nacos/31

服務註冊中心對比

Nacos全景圖所示

Nacos和CAP


AP/CP切換

Nacos支援AP和CP模式的切換
C是所有節點在同一時間看到的資料是一致的; 而A的定義是所有的請求都會收到響應。

何時選擇使用何種模式?
一般來說,
如果不需要儲存服務級別的資訊且服務例項是通過nacos client註冊,井能夠保持心跳上報,那麼就可以選擇AP模式。當前主流的服務如Spring cloud和Dubbo服務,都適用於AP模式,AP模式為了服務的可能性而減弱了一致性, 因此AP模式下只支援註冊時例項。

如果需要在服務級別編輯或者儲存配置資訊,那麼CP是必須,K8S服務和DNS服務則適用於CP模式。
CP模式下則支援註冊持久化例項,此時則是以Raft協議為叢集執行模式,該模式下注冊例項之前必須先註冊服務,如果服務不存在,則會返回錯誤。

curl -X PUT '$NACOS_ SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

Nacos作為服務配置中心演示

Nacos作為配置中心-基礎配置

cloudalibaba-config-nacos-client3377

POM

<dependencies>
    <!-- nacos config-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!-- SpringCloud ailibaba nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency><!-- 引用自己定義的api通用包,可以使用Payment支付Entity -->
        <groupId>com.eiletxie.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--監控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--熱部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

YML

bootstrap

server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服務註冊中心地址
      config:
        server-addr: localhost:8848 #Nacos作為配置中心地址
        file-extension: yaml #指定yaml格式配置

application

spring:
  profiles:
    active: dev #表示開發環境

why配置兩個

Nacos同springcloud-config-樣,在專案初始化時,要保證先從配置中心進行配置拉取,拉取配置之後,才能保證專案的正常啟動。

springboot中配置檔案的載入是存在優先順序順序的,bootstrap優先順序高於application

主啟動類

@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {

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

業務類

ConfigClientController

@RestController
@RefreshScope // 支援Nacos的動態重新整理功能
public class ConfigClientController {

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }
}

@RefreshScope動態重新整理,忘了嗎?

在Nacos中新增配置資訊

Nacos中的匹配規則

理論

Nacos中的dataid的組成格式及與SpringBoot配置檔案中的匹配規則

官網

實操

配置新增


nacos-config-client-dev

Nacos介面配置對應

設定DataId

  • 公式:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
  • prefix預設為spring.application.name的值
  • spring.profile.active即為當前環境對應的profile,可以通過配置項spring.profile.active來配置。
  • file-exetension為配置內容的資料格式,可以通過配置項speing.cloud.nacos.config.file-extension配置
  • 小總結說明
歷史配置
  • Nacos會記錄配置檔案的歷史版本預設保留30天,此外還有一件回滾功能
  • 回滾

測試

  • 啟動前需要在nacos客戶端-配置管理-配置管理欄目下有對應的yaml配置檔案
  • 執行cloud-config-nacos-client3377的主啟動類
  • 呼叫介面檢視配置資訊
    http://localhost:3377/config/info

自帶動態重新整理

修改下Nacos中的yaml配置檔案,再次呼叫檢視配置的介面,就會發現配置已經重新整理

Nacos作為配置中心-分類配置

問題

多環境多專案管理
問題1:
實際開發中,通常-個系統會準備
dev開發環境
test測試環境
prod生產環境。
如何保證指定環境啟動時服務能正確讀取到Nacos上相應環境的配置檔案呢?

問題2:
一個大型分散式微服務系統會有很多微服務子專案,
每個微服務專案又都會有相應的開發環境、測試環境、預發環境、正式環境....
那怎麼對這些微服務配置進行管理呢?

Nacos的圖形化管理介面

配置管理

名稱空間

Namespace+group+data ID三者關係?為什麼這麼設計?

  1. 是什麼
    類似Java裡面的package名和類名
    最外層的namespace是可以用於區分部署環境的,Group和DatalD邏輯 上區分兩個目標物件。

  2. 三者情況

預設情況:
Namespace= public, Group=DEFAULT_ GROUP,預設Cluster是DEFAULT

Nacos預設的名稱空間是public, Namespace主要用來實現隔離。
比方說我們現在有三個環境:開發、測試、生產環境,我們就可以建立E個Namespace, 不同的Namespace之間是隔離的。

Group預設是DEFAULT_ GROUP, Group可以把不同的微服務劃分到同一個分組裡面去

Service就是微服務; 一個Service可以包含多 個Cluster (叢集),Nacos預設Cluster是DEFAULT, Clyster是對指定微服務的一個虛擬劃分。
比方說為了容災,將Service微服務分別部署在了杭州機房和廣州機房,
這時就可以給杭州機房的Service微服務起一個叢集名稱(HZ),
給廣州機房的Service微服務起一個叢集名稱 (GZ) ,還可以儘量讓詞一個機房的微服務互相呼叫,以提升效能。

最後是Instance,就是微服務的例項。

Case

三種方案載入配置

DataID方案

指定spring.profile.active和配置檔案的DataID來使不同環境下讀取不同的配置
預設空間+預設分組+新建dev和test兩個DataID
新建dev配置DataID

新建test配置DataID

通過spring.profile.acvice屬性就能進行多環境下配置檔案的讀取

測試
  • http://localhost:3377/config/info
  • 配置什麼就載入什麼
    test

Group方案

通過Group實現環境區分

新建Group

在nacos圖形介面控制檯上新建配置檔案DataID

bootstrap+application

在config下增加一條group的配置即可。可配置為DEV_GROUP或TEST_GROUP

Namespace方案

新建dev/test的Namespace

回到服務管理-服務列表檢視

按照域名配置填寫

YML

Nacos叢集和持久化配置(重要)

官網說明

https://nacos.io/zh-cn/docs

官網架構圖

上圖翻譯

說明

預設Nacos使用嵌入式資料庫實現資料的儲存。所以,如果啟動多個預設置下的Nacos節點,資料儲存是存在一致性問題的。
為了解決這個問題,Nacos採用了集中式儲存的方式來支援叢集化部署,目前只支援MySQL的儲存。

按照上說,我們需要mysql資料庫

官網說明

https://nacos.io/zh-cn/docs/deployment.html

重點說明

Nacos持久化配置解釋

Nacos預設自帶的是嵌入式資料庫derby

derby到mysql切換配置步驟

nacos-server-1.1.4\nacos\conf目錄下找到sql指令碼

nacos-mysql.sql
執行指令碼

這裡說一下具體操作,你自己新建一個nacos_config的資料庫,將對應的sql檔案開啟,複製命令執行即可

nacos-server-1.1.4\nacos\conf目錄下找到application.properties

啟動Nacos,可以看到是個全新的空記錄介面,以前是記錄進derby

Linux版Nacos+MySQL生產環境配置

預計需要,1個nginx+3個nacos註冊中心,1個mysql

Nacos下載Liunx版

  • https://github.com/alibaba/nacos/releases
  • nacos-server-1.1.4.tar.gz
  • 解壓後安裝

叢集配置步驟

1.Linux伺服器上mysql資料庫配置

  • SQL指令碼在哪裡
  • sql語句原始檔
    nacos-mysql.sql
  • 自己Linux機器上Mysql資料庫貼上

2.application.properties配置

位置

內容

3.Linux伺服器上nacos的叢集配置cluster.conf

梳理出3臺nacos機器的不同服務埠號
複製出cluster.conf

內容


這個IP不能寫127.0.0.1,必須是Linux命令hostname -i能夠識別的IP

4.編輯Nacos的啟動指令碼startup.sh,使他能夠接受不同的啟動埠

/mynacos/nacos/bin 目錄下有startup.sh
在什麼地方,修改什麼,怎麼修改
思考

/mynacos/nacos/bin目錄下有startup.sh

平時單機版的啟動,都是./startup.sh即可。

但是

叢集啟動,我們希望可以類似其它軟體的shell命令,傳遞不同的埠號啟動不同的nacos例項。
命令: ./startup.sh -p 3333表示啟動埠號為3333的nacos伺服器例項,和上一步的cluster.conf配置的一致。

修改內容



執行方式

5.Nginx的配置,由它作為負載均衡器

修改nginx的配置檔案

nginx.conf


按照指定啟動

6.截至到此為止,1個nginx+3個nacos註冊中心+mysql

測試通過nginx訪問nacos

http://192.168.111.144:1111/nacos/#/login

新建一個配置測試
linux伺服器的mysql插入一條記錄

測試

微服務springalibaba-provider-payment9002啟動註冊進nacos叢集

yml

server:
  port: 9002

spring:
  application:
    name: nacos - payment -provider
  cloud:
    nacos :
      discovery:
        #配置Nacos地址
    #server-addr: localhost:8848
        #換成nginx的1111埠,做叢集
    server-addr: 192. 168.111.144:1111

management:
  endpoints:
    web:
      exposure:
        include: *'
結果

高可用小總結