Nacos之原理講解和使用
1 Nacos
1.1 簡介
Nacos
致力於幫助您發現、配置和管理微服務。Nacos
提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元資料及流量管理。
Nacos
幫助您更敏捷和容易地構建、交付和管理微服務平臺。Nacos
是構建以服務
為中心的現代應用架構 (例如微服務正規化、雲原生正規化) 的服務基礎設施。
1.2 下載以及安裝
下載地址:https://github.com/alibaba/Nacos/releases
直接點進去
根據需要選擇win或者linux版本
1.2.1 Linux安裝啟動
- 把我們的
Nacos
包解壓 :tar -zxvf nacos-server-1.1.4.tar.gz
- cd 到我們的解壓目錄nacos :
cd nacos
- 進入到
bin
目錄下 執行命令(啟動單機
)sh startup.sh -m standalone
- 訪問
nacos
的服務端http://127.0.0.1:8848/nacos/index.html
,預設的使用者名稱密碼是 nacos/nacos
如下圖所示:
- 停止nacos在nacos/bin目錄下,執行
sh shutdown.sh
1.2.2 Windowns安裝啟動
相關命令如下所示:
1.3 Nacos 主要特點
1.3.1 服務發現和服務健康監測
-
Nacos
支援基於DNS
和基於RPC
的服務發現。服務提供者使用原生SDK、OpenAPI
、或一個獨立的Agent TODO
註冊Service
後,服務消費者可以使用DNS TODO
或HTTP&API
查詢和發現服務。 -
Nacos
提供對服務的實時的健康檢查,阻止向不健康的主機或服務例項傳送請求。Nacos
支援傳輸層 (PING 或 TCP
)和應用層 (如HTTP、MySQL
、使用者自定義)的健康檢查。對於複雜的雲環境和網路拓撲環境中(如VPC
、邊緣網路等)服務的健康檢查,Nacos
提供了agent
上報模式和服務端主動檢測2種健康檢查模式。Nacos
還提供了統一的健康檢查儀表盤,幫助您根據健康狀態管理服務的可用性及流量。
1.3.2 動態配置服務
- 動態配置服務可以讓你以中心化、外部化和動態化的方式管理所有環境的應用配置和服務配置。
- 動態配置消除了配置變更時重新部署應用和服務的需要,讓配置管理變得更加高效和敏捷。
- 配置中心化管理讓實現無狀態服務變得更簡單,讓服務按需彈性擴充套件變得更容易。
-
Nacos
提供了一個簡潔易用的UI (控制檯樣例 Demo) 幫助您管理所有的服務和應用的配置。Nacos
還提供包括配置版本跟蹤、金絲雀釋出、一鍵回滾配置以及客戶端配置更新狀態跟蹤在內的一系列開箱即用的配置管理特性,幫助您更安全地在生產環境中管理配置變更和降低配置變更帶來的風險。
1.3.3 動態 DNS 服務
- 動態
DNS
服務支援權重路由,讓你更容易地實現中間層負載均衡、更靈活的路由策略、流量控制以及資料中心內網的簡單DNS
解析服務。動態DNS
服務還能讓您更容易地實現以DNS
協議為基礎的服務發現,以幫助你消除耦合到廠商私有服務發現API
上的風險。 -
Nacos
提供了一些簡單的DNS APIs TODO
幫助您管理服務的關聯域名和可用的 IP:PORT 列表。
小節一下:
-
Nacos
是阿里開源的,支援基於DNS
和基於RPC
的服務發現。 -
Nacos
的註冊中心支援CP
也支援AP
,對他來說只是一個命令的切換,隨你玩,還支援各種註冊中心遷移到Nacos
,反正一句話,只要你想要的他就有。 -
Nacos
除了服務的註冊發現之外,還支援動態配置服務,一句話概括就是Nacos
=Spring Cloud註冊中心
+Spring Cloud配置中心
1.3.4 Nacos領域模型劃分以及概念詳解
NameSpace
(預設的NameSpace
是public
NameSpace
可以進行資源隔離,比如我們dev
環境下的NameSpace
下的服務是呼叫不到prod
的NameSpace
下的微服務)
1.4 Nacos服務端搭建
1.4.1 加入依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐alibaba‐nacos‐discovery</artifactId>
</dependency>
1.4.2 寫註解(也可以不寫) @EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class Tulingvip01MsAlibabaNacosClientOrderApplication {
public static void main(String[] args) {
SpringApplication.run(Tulingvip01MsAlibabaNacosClientOrderApplication.class, args);
}
}
附:@EnableDiscoveryClient
和@EnableEurekaClient
- 共同點:都是能夠讓註冊中心能夠發現,掃描到該服務
- 不同點:
@EnableEurekaClient
只適用於Eureka
作為註冊中心,@EnableDiscoveryClient
可以是其他註冊中心
1.4.3 配置檔案
注意
:server-addr
:不需要寫協議
spring:
application:
name: order‐center
cloud:
nacos:
discovery:
server-addr: localhost:8848
登入Nacos看看是否有服務:
1.4.4 驗證服務
驗證我們的服務是否註冊到我們的nacos
上
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/getServiceList")
public List<ServiceInstance> getServiceList() {
List<ServiceInstance> serviceInstanceList =
discoveryClient.getInstances("order‐center");
return serviceInstanceList;
}
1.5 Nacos配置管理
Nacos作為配置,可以做到不用重啟服務而動態重新整理配置
微服務接入配置中心的步驟
1.5.1 新增依賴
新增依賴包spring-cloud-alibaba-nacos-config
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐alibaba‐nacos‐config</artifactId>
</dependency>
1.5.2 編寫精準配置
編寫配置檔案,需要寫一個bootstrap.yml
配置檔案
配置解釋 :
-
server-addr: localhost:8848
: 表示我微服務怎麼去找我的配置中心 -
spring.application.name=order-center
: 表示當前微服務需要向配置中心索要order-center的配置 -
spring.profiles.active=prod
: 表示我需要向配置中心索要order-center的生產環境的配置 - 索要檔案的格式為 :
${application.name}- ${spring.profiles.active}.${file-extension}
spring:
application:
name: order‐center
profiles:
active: prod
cloud:
nacos:
config:
server-addr: localhost:8848
file‐extension: yml
真正在nacos
配置中心上 就是 order-center-prod.yml
1.5.3 通用配置(shared‐dataids)
通用配置
指把該配置提取為一個公共配置yml
,提供給所有的工程使用
通過shared‐dataids
配置,越排到後面的公共配置yml優先順序越高
spring:
application:
name: order‐center
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
file‐extension: yml
#各個微服務共享的配置,注意越排到後面的公共配置yml優先順序越高
shared‐dataids: common.yml,common2.yml
#支援動態重新整理的配置檔案
refreshable‐dataids: common.yml,common2.yml
配置優先順序:
NacosPropertySource {name='order-center-dev.yml'},
NacosPropertySource {name='order-center.yml'},
NacosPropertySource {name='common2.yml'},
NacosPropertySource {name='common.yml'}
1.5.4 通用配置(ext-config)
通過ext-config
方式,同樣配置到越後面的配置 優先順序越高extension-configs
是nacos-config
的jar包是2.2.6版本的,在此版本中ext-config
提示已過時
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
file‐extension: yml
extension-configs[0]:
data-id: common3.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[1]:
data-id: common4.yml
group: DEFAULT_GROUP
refresh: true
或者如下:
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
file‐extension: yml
ext-config:
- data-id: common3.yml
group: DEFAULT_GROUP
refresh: true
- data-id: common4.yml
group: DEFAULT_GROUP
refresh: true
1.5.5 各個配置優先順序
精準配置
>不同環境的通用配置
>不同工程的(ext-config)
>不同工程
精準配置
會覆蓋 與通用配置
相同的配置,然後再和通用配置互補
spring:
application:
name: order‐center
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
file‐extension: yml
shared‐dataids: common.yml,common2.yml
#支援動態重新整理的配置檔案
refreshable‐dataids: common.yml,common2.yml
ext-config:
- data-id: common3.yml
group: DEFAULT_GROUP
refresh: true
- data-id: common4.yml
group: DEFAULT_GROUP
refresh: true
上述配置 載入的優先順序 :
-
order-center-dev.yml
精準配置 -
order-center.yml
同工程不同環境的通用配置 -
ext-config
: 不同工程 通用配置
common4.yml
common3.yml -
shared-dataids
不同工程通用配置
common2.yml
common.yml
1.6 Nacos叢集模式
1.6.1 搭建Nacos叢集
我們的nacosserver
(搭建三個叢集埠分別為8849 ,8850,8851
)
我們以配置一臺為例(8849)為例
- 修改
nacos8849/conf
檔案application.properties
,配置資料庫連結
spring.datasource.platform=mysql
# 資料庫例項數量
db.num=1
//自己資料庫的連線資訊
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_test?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root
建立一個數據庫(需要自己建立一個數據庫) 指令碼的位子在nacos/conf/nacos-mysql.sql
- 修改
nacos8849/conf
檔案 把原來的cluster.conf.example
改為cluster.conf
檔案
檔案內容為如下
到此為止nacos8849
安裝完成了而nacos8850
和nacos8851
同樣安裝 - 修改
nacos-server
的啟動指令碼jvm
引數
- 分別啟動 8849 8850 8851
登入後檢視叢集管理
1.6.2 Nacos叢集選舉機制
Nacos
作為配置中心的功能是基於Raft
演算法來實現的。
Raft
演算法是分散式系統開發首選的共識演算法,它通過一切以領導者為準
的方式,實現一系列值的共識和各節點日誌的一致。
Raft
選舉過程涉及三種角色和任期(Term):
-
Follower
:默默地接收和處理來自Leader
的訊息,當等待Leader
心跳資訊超時的時候,就主動站出來,推薦自己當Candidate
。 -
Candidate
:向其他節點發送投票請求,通知其他節點來投票,如果贏得了大多數(N/2+1
)選票,就晉升Leader
-
Leader
:負責處理客戶端請求,進行日誌複製等操作,每一輪選舉的目標就是選出一個領導者;領導者會不斷地傳送心跳資訊,通知其他節點“我是領導者,我還活著,你們不要發起新的選舉,不用找個新領導者來替代我。” -
Term
:這跟民主社會的選舉很像,每一屆新的履職期稱之為一屆任期
領導選舉過程
-
在初始時,叢集中所有的節點都是
Follower
狀態,都被設定一個隨機選舉超時時間(一般150ms-300ms): -
如果
Follower
在規定的超時時間,都沒有收到來自Leader
的心跳,它就發起選舉:將自己的狀態切為Candidate
,增加自己的任期編號,然後向叢集中的其它Follower
節點發送請求,詢問其是否選舉自己成為Leader
: -
其他節點收到候選人A的請求投票訊息後,如果在編號為1的這屆任期內還沒有進行過投票,那麼它將把選票投給節點A,並增加自己的任期編號:
-
當收到來自叢集中過半節點的接受投票後,A節點即成為本屆任期內
Leader
,他將週期性地傳送心跳訊息,通知其他節點我是Leader
,阻止Follower
發起新的選舉:
選舉的幾種情況 :
- 第一種情況,贏得選舉之後,
leader
會給所有節點發送訊息,避免其他節點觸發新的選舉 - 第二種情況,比如有三個節點A B C。A B同時發起選舉,而A的選舉訊息先到達C,C給A投了一票,當B的訊息到達C時,已經不能滿足上面提到的約束條件,即C不會給B投票,而A和B顯然都不會給對方投票。A勝出之後,會給B,C發心跳訊息,節點B發現節點A的
term
不低於自己的term
,知道有已經有Leader
了,於是轉換成follower
- 第三種情況, 沒有任何節點獲得
majority
投票,可能是平票的情況。加入總共有四個節點(A/B/C/D),Node C、Node D同時成為了candidate
,但Node A投了NodeD一票,NodeB投了Node C一票,這就出現了平票split vote
的情況。這個時候大家都在等啊等,直到超時後重新發起選舉。如果出現平票的情況,那麼就延長了系統不可用的時間,因此raft引入了 randomizedelection timeouts來儘量避免平票情況