Spring Cloud 集成 Nacos 實現服務治理和配置中心

什么是 Nacos?官方直通車

Nacos集成

一、Nacos 服務搭建

1.1 環境準備

  1. 騰訊云 Linux centos 7.5 64位
  2. 本地windows 64 bit JDK 1.8;
  3. 本地 Maven 3.6.3;

1.2 下載安裝

  • 下載源碼并打包源碼包(PS,也可以直接下載源碼包)
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U  
ls -al distribution/target/
  • 上傳源碼包并解壓縮到云服務器
tar -xvf nacos-server-$version.tar.gz

1.3 運行 nacos server

Nacos支持三種運行模式:

  • 單機模式:用于測試和單機試用
  • 集群模式:用于生產環境,確保高可用
  • 多集群模式:用于多數據中心場景

單機模式

cd nacos/bin
[root@VM-0-5-centos bin]# ll
total 32
-rw-r--r-- 1 root root  720 Sep 20 20:35 derby.log
drwxr-xr-x 2 root root 4096 Sep 22 19:04 logs
-rwxr-xr-x 1 root root  978 Sep 20 15:16 shutdown.cmd
-rwxr-xr-x 1 root root  979 Sep 20 15:16 shutdown.sh
-rwxr-xr-x 1 root root 3535 Sep 20 15:16 startup.cmd
-rwxr-xr-x 1 root root 5028 Sep 20 20:07 startup.sh
drwxr-xr-x 3 root root 4096 Sep 20 20:08 work

啟動命令(standalone代表著單機模式運行,非集群模式):
sh startup.sh -m standalone
ps: 
1. 首次啟動可能存在sh權限問題,需要對sh進行賦權
chmod +x startup.sh
2. 首次啟動可能報.sh line 2 :$'\r': command not found
原因是 windows 下的換行符是 \r\n,而 linux 下的換行符是 \n
解決方案: 
# 安裝 dos2unix
yum install dos2unix -y
# 執行命令
dos2unix startup.sh
# 關閉頁面,后臺運行
./startBatch.sh & 

單機模式支持mysql
nacos 0.7 以后支持mysql數據源:

  • 安裝mysql 5.6.5+
  • 創建nacos database, 初始化nacos-mysql.sql
  • 修改conf/application.properties文件,增加支持mysql數據源配置(目前只支持mysql),添加mysql數據源的url、用戶名和密碼。
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=root

再以單機模式啟動nacos,nacos所有寫嵌入式數據庫的數據都寫到了mysql。
訪問nacos控制臺

遇到的坑,在首次啟動后臺服務器報錯:jmenv.tbsite.net

aused by: com.alibaba.nacos.api.exception.NacosException: java.net.UnknownHostException: jmenv.tbsite.net
        at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.run(AddressServerMemberLookup.java:110)
        at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.start(AddressServerMemberLookup.java:66)
        at com.alibaba.nacos.core.cluster.ServerMemberManager.initAndStartLookup(ServerMemberManager.java:156)
        at com.alibaba.nacos.core.cluster.ServerMemberManager.init(ServerMemberManager.java:144)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
        ... 111 common frames omitted

解決辦法是,conf中只給了一個cluster.conf.example文件,需要copy成一個cluster.conf即可。

集群模式

多集群模式

二、Spring Cloud nacos注冊中心和配置中心集成

  • 通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 實現服務的注冊與發現。
  • 通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 實現配置的動態管理。

Spring Cloud可以實現零代碼切換到Nacos注冊中心,只需要引入nacos依賴并增加配置nacos注冊中心。
版本說明:

 <spring-boot-dependencies.version>2.2.9.RELEASE</spring-boot-dependencies.version>
 <spring-cloud-dependencies.version>Hoxton.SR8</spring-cloud-dependencies.version>
 <spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>

截止2020.09.22 spring-cloud-alibaba 僅支持Spring Boot 2.2.x

2.1 Nacos 快速集成

  • 引入Nacos client 依賴
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
  • 通過Spring Cloud 原生注解開啟注冊服務以及自動刷新配置功能
package com.qt.mall;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@EnableDiscoveryClient
@RefreshScope
@SpringBootApplication
public class NacosServiceApplication {

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

}

  • 在配置中增加nacos地址、注冊應用名稱、配置中心配置
    bootstrap.yml
# mvn 命令啟動添加--spring.profiles.active=test
spring:
  application:
    name: nacos-service
  profiles:
    active: dev

bootstrap-dev.yml

spring:
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        server-addr: 120.53.121.130
        namespace: 180d5ec1-9253-4c55-a018-e27e609b83f3
        #ip: 192.168.128.41
      config:
        server-addr: 120.53.121.130
        file-extension: yml
        group: nacos-service
        namespace: 180d5ec1-9253-4c55-a018-e27e609b83f3
  • 登錄nacos控制臺,增加配置



  • 啟動服務,驗證注冊服務和配置中心結果



2.2 配置說明

nacos除了核心注冊中心、配置中心連接配置外,可以實現代碼零配置解決方案。
nacos動態配置服務可以讓系統以中心化、外部化和動態化的方式管理所有環境的應用配置和服務配置。

  • spring.application.name:注冊服務名稱,也是構成 Nacos 配置管理 dataId字段的一部分。
# 在 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 類型。

2.3 Nacos數據隔離模式

Nacos提供四層的數據隔離模式:

nacos數據隔離模型

  • Company:用戶賬號對應的可能是一個企業或者獨立的個體,這個數據一般情況下不會透傳到服務注冊中心。
  • Namespace: 一個用戶賬號可以新建多個命名空間,每個命名空間對應一個客戶端實例,這個命名空間對應的注冊中心物理集群是可以根據規則進行路由的,這樣可以讓注冊中心內部的升級和遷移對用戶是無感知的,同時可以根據用戶的級別,為用戶提供不同服務級別的物理集群。Namespace常用于進行租戶粒度的配置隔離。不同的命名空間下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用場景之一是不同環境的配置的區分隔離,例如開發測試環境和生產環境的資源(如配置、服務)隔離等。
  • Group:Nacos 中的一組配置集,是組織配置的維度之一。通過一個有意義的字符串(如 Buy 或 Trade )對配置集進行分組,從而區分 Data ID 相同的配置集。當您在 Nacos 上創建一個配置時,如果未填寫配置分組的名稱,則配置分組的名稱默認采用 DEFAULT_GROUP 。配置分組的常見場景:不同的應用或組件使用了相同的配置類型,如 database_url 配置和 MQ_topic 配置。
  • Service:服務是指一個或一組軟件功能(例如特定信息的檢索或一組操作的執行),其目的是不同的客戶端可以為不同的目的重用(例如通過跨進程的網絡調用)。Nacos 支持主流的服務生態,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service.

三、高級應用

3.1 基于Namespace命名空間的資源隔離

根據Nacos不同的Namespace下,可以存在相同的 Group 或 Data ID 的配置的數據隔離特性,我們可以很好的實現同一Nacos Server集群統一管理項目不同環境的資源(注冊服務實例、配置等)

  • 定義各個環境命名空間


    命名空間管理
  • 多環境配置支持
    基于spring.profile.active,增加應用的多環境配置支持,不同環境配置對應的Nacos命名空間,根據應用啟動的環境變量參數自動識別對應的Nacos配置


    多環境支持
# dev配置
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.128.20
        namespace: 1c53b59e-9f3d-44a4-b2d7-5faaea25b3c6 # dev 環境的命名空間
        ip: 192.168.128.20
      config:
        server-addr: 192.168.128.20
        file-extension: yml
        group: ds-user-center-server
        namespace: 1c53b59e-9f3d-44a4-b2d7-5faaea25b3c6 # dev 環境的命名空間
        shared-configs:
          - data-id: mqclient-config-share.yml
            group: MQCLIENT_GROUP
            refresh: true
        extension-configs:
          - data-id: global-public-share.yml
            group: share
            refresh: true
          - data-id: resource-service-public-share.yml
            group: share
            refresh: true

test、qa、prod配置類似。

3.2 Nacos自定義配置

Nacos除了支持file-extension模式的data-id.yml或data-id.properties的配置外, 自0.2.1版本以后還支持自定義的data-id的配置。目前主要支持shared-configs模式和extension-configs模式,配置示例:

      shared-configs:
          - data-id: mqclient-config-share.yml
            group: MQCLIENT_GROUP
            refresh: true
        extension-configs:
          - data-id: global-public-share.yml
            group: share
            refresh: true
          - data-id: resource-service-public-share.yml
            group: share
            refresh: true

3.2.1 配置優先級

綜上,Spring Cloud Alibaba Nacos Config 提供了三種配置能力從 Nacos 拉取相關的配置。

A: 通過 spring.cloud.nacos.config.shared-configs[n].data-id 支持多個共享 Data Id 的配置
B: 通過 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多個擴展 Data Id 的配置
C: 通過內部相關規則(應用名、應用名+ Profile )自動生成相關的 Data Id 配置

當三種方式共同使用時,他們的一個優先級關系是:A < B < C
Nacos-config

3.3 Nacos配置灰度發布

Nacos 1.1.0版本以后,支持灰度配置。Nacos配置的灰度發布是基于Nacos配置中心Beta發布功能進行實現,默認不勾選該功能。
灰度配置流程如下:

  • 預備同一應用兩個節點:

192.168.132.49
192.168.128.20

  • 在Nacos配置中心執行Beta發布,指定只發布到49節點機器,將配置suffixurl 和 shortSuffixurl
    suffixurl: http://%s.easymall-dev01.com
    shortSuffixurl: all.easymall-dev01.com
    灰度發布

查看日志,可以驗證到49機器配置發布生效:
而20機器,無任何反應,說明配置未發布到20:


49Nacos配置更新日志

20服務日志無任何打印輸出

進一步通過接口驗證灰度發布是否生效,可以看到49發布的配置已經生效,而20機器接口仍是灰度發布前配置內容。


49配置生效

20配置未生效

灰度驗證通過后,關閉灰度,將配置正式發布,再次驗證20機器接口,可以發現配置也生效


20配置生效

3.4 基于Nacos元數據實現Spring Cloud 微服務灰度發布實踐

應用迭代過程中會不斷有新版本API發布,在新版本正式發布前,可以使用灰度流量控制先進行小規模驗證,將升級帶來的影響限定在指定的用戶范圍內可以最大程度上保障線上業務的穩定運行,通過收集使用體驗的數據,對應用新版本的功能、性能、穩定性等指標進行評判,然后再全量升級。

這里主要參考了Nepxion 灰度框架。

3.4.1 調用鏈分析

外部調用

web請求 ==> Gateway ==> 服務
GateWay 轉發請求時,會根據Ribbon(目前采用輪詢策略)從服務實例選擇對應服務進行轉發

內部調用

請求 ==> Feign調用==> 服務
目前內部服務間調用沒有經過網關,而是直接根據Ribbon(目前采用輪詢策略)從服務實例選擇對應服務進行接口調用。

3.4.2 預備知識

Nacos元數據

Nacos數據(如配置和服務)描述信息,如服務版本、權重、容災策略、負載均衡策略、鑒權配置、各種自定義標簽 (label),從作用范圍來看,分為服務級別的元信息、集群的元信息及實例的元信息。
設置Nacos元數據

# Nacos config for qt
spring.cloud.nacos.discovery.metadata.group=qt-service-group   #定義所屬組,也可以通過服務名前綴來自動產生服務組名
spring.cloud.nacos.discovery.metadata.version=1.0     #定義版本號 也可以通過Git插件方式自動產生版本號
spring.cloud.nacos.discovery.metadata.region=dev  定義區域
spring.cloud.nacos.discovery.metadata.env=env1   定義環境
spring.cloud.nacos.discovery.metadata.zone=zone1  #定義所屬可用區

3.4.3 實現方案

實現思路

  • 根據應用注冊的實例元數據來實現灰度,比如選擇version來標記灰度版本:
spring.cloud.nacos.discovery.metadata.version=1.1 
  • 基于網關為灰度觸點,自定義Gate Way Filter, 實現從Spring Cloud Gateway發起的調用都走版本為x.x的服務或者Spring Cloud Gateway發起的調用按照配置的的灰度策略,如A:1.1 ==> 網關 B:1.2 ==> 網關==>C:1.3。
  • 基于Ribbon權重負責均衡,實現從Spring Cloud Gateway發起的調用1.0版本流量調用為90%,1.1流量調用為10%

元數據動態指定
外部系統(例如:運維發布平臺)在遠程啟動微服務的時候,可以通過參數傳遞來動態改變元數據或者增加運維特色的參數,最后注冊到遠程配置中心。有如下兩種方式

  • 通過Program arguments來傳遞,它的用法是前面加“--”,支持Nacos的增量覆蓋。例如:
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port=1100 --spring.cloud.nacos.discovery.metadata.version=1.0"
  • 通過VM arguments來傳遞,它的用法是前面加“-D”。推薦使用該方式。例如:-Dmetadata.version=1.0
  • 兩種方式盡量避免同時用

實現流程

灰度發布

實現場景
通過外部參數動態指定A、B、C服務灰度版本為2.0。

  1. 基于Header傳遞的灰度路由模式,通過http工具,傳遞Http Header,比如version=2.0,網關根據header動態路由到灰度服務,而不帶header的依舊請求到初始版本。

  2. 前后端灰度,當前端(例如:APP)和后端微服務同時存在多個版本時,可以采用“前端灰度&網關灰度路由組合式策略”,前端調用網關時,傳入前端app版本號,網關根據路由策略,路由要相關的灰度服務。

  1. APP v1.0 -> 網關 -> A服務 v1.0 -> B服務 v1.0
  2. APP v1.1 -> 網關 -> A服務 v1.1 -> B服務 v1.1
  1. 基于Nacos配置中心的全局訂閱的灰度策略,基于header的灰度策略,在全鏈路下,實現可能比較復雜,Nacos全局訂閱實現方式提供了簡單的方式規避了header傳遞。

3.4.4 主要的功能點

  • Nacos服務實例元數據相關,支持從外部參數動態獲取元數據。
  • 自定義網關Filter,實現請求header偵測,灰度路由解析、灰度動態路由等功能
  • 自定義Ribbon負載均衡策略,實現灰度流量控制策略
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375