Nacos集成
一、Nacos 服務搭建
1.1 環境準備
- 騰訊云 Linux centos 7.5 64位
- 本地windows 64 bit JDK 1.8;
- 本地 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
來配置。目前只支持properties
和yaml
類型。
2.3 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:
進一步通過接口驗證灰度發布是否生效,可以看到49發布的配置已經生效,而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。
基于Header傳遞的灰度路由模式,通過http工具,傳遞Http Header,比如version=2.0,網關根據header動態路由到灰度服務,而不帶header的依舊請求到初始版本。
前后端灰度,當前端(例如:APP)和后端微服務同時存在多個版本時,可以采用“前端灰度&網關灰度路由組合式策略”,前端調用網關時,傳入前端app版本號,網關根據路由策略,路由要相關的灰度服務。
- APP v1.0 -> 網關 -> A服務 v1.0 -> B服務 v1.0
- APP v1.1 -> 網關 -> A服務 v1.1 -> B服務 v1.1
- 基于Nacos配置中心的全局訂閱的灰度策略,基于header的灰度策略,在全鏈路下,實現可能比較復雜,Nacos全局訂閱實現方式提供了簡單的方式規避了header傳遞。
3.4.4 主要的功能點
- Nacos服務實例元數據相關,支持從外部參數動態獲取元數據。
- 自定義網關Filter,實現請求header偵測,灰度路由解析、灰度動態路由等功能
- 自定義Ribbon負載均衡策略,實現灰度流量控制策略