配置中心
概述
配置中心是微服務中不可或缺的組件,因為如果沒有配置中心,那么各個微服務的的配置信息無法得到統一和管理,會變得冗余。
:::color4
配置中心是用于管理應用程序配置信息的工具
- 集中管理配置:解決微服務架構下配置分散和冗余問題,將原本分散在各個服務節點的配置信息集中存儲與管理 ,便于統一維護和管理,避免手動配置導致的不統一和不便。
- 貫穿應用生命周期:應用啟動和運行時,都需讀取配置信息,配置中心提供配置讀取功能,應用在啟動時依配置初始化,運行中依配置調整行為。
- 支持動態更新:主流配置中心如 Spring Cloud Config、Apollo、Nacos 等,支持配置實時推送、版本管理、配置回滾等功能,可在不重啟應用的情況下動態更新配置,提升運維效率和系統靈活性。
- 適配多種環境:應用在開發、測試、生產等不同環境,以及不同集群中,配置需求不同,配置中心可進行完善的環境、集群配置管理,讓同一程序在不同環境下按需加載配置。
- 多語言和多部署方式支持: 滿足不同技術棧和部署場景需求,主流配置中心大多支持多語言,且提供單機和分布式等多種部署方式。
:::
Nacos
安裝Nacos
注意:Nacos 會通過心跳機制來檢測服務實例的健康狀態。當一個服務實例注冊到 Nacos 后,該實例會定期向 Nacos Server 發送心跳包 ,以表明自己處于存活狀態。如果 Nacos Server 在一定時間內沒有收到某個服務實例的心跳(即心跳超時),就會將這個服務實例從可用實例列表中剔除,這樣其他服務在進行服務發現時,就不會獲取到這個已被剔除的不健康實例,從而避免調用失敗。
配置外部數據庫連接
1.在本地mysql中,執行nacos中的sql文件(nacos-mysql.sql)先創建nacao表
2.再將nacos中的application.properties中的msyql連接改為本地的賬號、密碼等
3.重啟nacos(如果成功了會出現use external …)
【注意:此時的數據庫是空的,并不會將之前nacos中的數據遷移過來,所以建議在最開始就進行外部數據庫連接,如果想要遷移,可以先登錄舊的nacos中進行導出,然后在新的nacos中進行導入即可】
配置相關理論介紹
- Namespace(命名空間): Nacos 的全局資源隔離機制,通俗理解為 “不同環境的獨立容器”,例如用不同 Namespace 隔離開發、測試、生產環境的服務和配置,確保環境間互不干擾。
- namespace= online、preonline、test、dev 等不同的隔離環境
- Group(分組):同一命名空間內的資源歸類方式,通俗理解為 “同一環境里的文件夾”,例如在生產環境 Namespace 中,用不同 Group 區分訂單服務、支付服務的配置,方便分類管理。
- Data ID:配置文件的唯一標識(里面的內容是具體的配置),通俗理解為 “文件夾里的具體配置文件”,例如訂單服務 Group 中的
<font style="color:rgb(0, 0, 0);">order-service-dev.properties</font>
,就是一個包含該服務所有配置的 Data ID。
Nacos的操作與使用
基于SpringCloudAlibaba的配置讀取
1??在yaml中填寫相關配置
- 該項目的主配置為config1,然后可以導入其他的配置(利用ext或者shared-dataids導入),并且這些配置都在namespace為400e0e05-e848-4d2d-a2f6-b6fba1209dd5的空間內
- ext和shared-dataids的區別是ext可以指定分組,但shared-dataids只能使用默認的分組DEFAULT_GROUP
- ext和shared-dataids的refresh都很重要,開啟后可以支持配置信息的動態刷新(即會實時改變)
# 服務器配置
server:port: 9002 # 應用啟動的端口號# Nacos配置說明:
# 配置文件的唯一標識由三部分組成:
# 命名空間(namespace) + 分組(group) + 數據ID(dataId)
spring:application:name: config1 # 應用名稱,會作為默認dataId的一部分(默認格式:${name}-${profile}.${extension})cloud:nacos:config:server-addr: 127.0.0.1:8848 # Nacos服務器地址# server-addr: 127.0.0.1:8860,127.0.0.1:8861,127.0.0.1:8862 # 集群地址(注釋掉的備用配置)file-extension: yaml # 配置文件的格式(默認是properties)namespace: 400e0e05-e848-4d2d-a2f6-b6fba1209dd5 # 命名空間ID(用于環境隔離)group: DEFAULT_GROUP # 默認分組(用于配置隔離)# 方式1:通過shared-dataids加載多個配置文件(注釋掉的備用配置)# shared-dataids: config2.yaml,config3.yaml,config4.yaml # 要加載的多個配置文件# refreshable-dataids: config3.yaml # 哪些配置支持動態刷新# 方式2:通過ext-config[n]加載多個配置文件(優先級更高,支持更細粒度配置)ext-config[0]:data-id: config2.yaml # 要加載的配置文件IDext-config[1]:data-id: config3.yaml # 要加載的配置文件IDgroup: CONFIG3_GROUP # 該配置所屬的分組(覆蓋默認group)ext-config[2]:data-id: config4.yaml # 要加載的配置文件IDgroup: CONFIG4_GROUP # 該配置所屬的分組refresh: true # 該配置支持動態刷新(配置變更后自動生效)
前面指定的config和下面的ext的關系- 基礎關系
spring.application.name: config1
定義了當前應用的名稱,Nacos 會默認加載以該名稱為基礎的配置文件(默認格式:config1.yaml
,結合 namespace 和 group)。
而ext-config
是額外的配置加載規則,用于加載當前應用需要的其他配置文件(如config2.yaml
、config3.yaml
等)。 - 配置優先級
ext-config
中指定的配置優先級高于默認配置(即config1.yaml
)。如果ext-config
中的配置與config1.yaml
有沖突,會以ext-config
的配置為準。
此外,ext-config
內部按數組下標遞增優先級依次提高(即ext-config[2]
優先級高于ext-config[1]
)。 - 作用場景
config1
通常是當前應用的主配置,而ext-config
用于引入公共配置(如數據庫、緩存配置)或其他模塊的配置,實現配置復用和解耦。
:::
- 使用configurableApplicationContext.getEnvironment().getProperty(“student.name”);的方式,可以直接動態刷新
- 使用@Value(指定key)+@RefreshScope也可以支持動態刷新
- 如果是獲取多個配置
- // 從配置中獲取config2.name(這個是key)的值,默認值為null
@Value("${config2.name:null}")
private String config2name;
package com.muse.nacos.server.nacosserver.controller;
// 導入必要的依賴包
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @description Nacos配置測試控制器* @author: muse**/
// @RefreshScope // 開啟配置自動刷新(當前注釋掉了,若啟用可讓@Value注解的屬性動態更新)
@RestController // 標識該類為REST風格的控制器,返回數據直接作為響應內容
public class NacosServerController {// 注入Spring上下文環境對象,用于動態獲取配置@Resourceprivate ConfigurableApplicationContext configurableApplicationContext;// 從配置中獲取student.name的值,默認值為null@Value("${student.name:null}")private String name;// 從配置中獲取config2.name的值,默認值為null@Value("${config2.name:null}")private String config2name; // 變量名應為config2Name// 從配置中獲取config3.name的值,默認值為null@Value("${config3.name:null}")private String config3name; // 變量名應為config3Name// 從配置中獲取config4.name的值,默認值為null@Value("${config4.name:null}")private String config4name; // 變量名應為config4Name/*** 測試接口:http://localhost:9002/name* 說明:* 如果只是通過@Value獲得的配置信息,不會隨著Nacos的修改操作而獲得最新配置信息。* 實時獲取最新配置信息有兩種方式:* 方式1:添加@RefreshScope注解。* 方式2:通過getProperty的方式,獲得最新的配置信息。** @return 配置信息對比結果*/@GetMapping("/name") // 映射GET請求到/name路徑public String getName() {// 方式2:通過上下文環境動態獲取最新的student.name配置String name1 = configurableApplicationContext.getEnvironment().getProperty("student.name");// 返回@Value獲取的值和動態獲取的值的對比return String.format("name=%s <br> name1=%s", name, name1);}/*** 測試接口:http://localhost:9002/allname* 用于獲取所有配置文件中的name屬性*/@GetMapping("/allname") // 映射GET請求到/allname路徑public String getAllName() {// 返回多個配置文件中的name屬性值return String.format("config1Name=%s<br> config2Name=%s<br> config3Name=%s<br> config4Name=%s", name, config2ame, config3ame, config4ame);}
}
集群配置讀取
原理
在測試環境中,直接配置多個集群地址讓springcloud感知即可
spring:application:name: config1 # 應用名稱,會作為默認dataId的一部分(默認格式:${name}-${profile}.${extension})cloud:nacos:config:server-addr: 127.0.0.1:8860,127.0.0.1:8861,127.0.0.1:8862 # 多個集群地址
如果其中一個節點掛了,則會自動用另外的
在生產環境中,通常不直接寫地址,而是通過slb(負載均衡)
- 生產環境中,通常會在 Nacos 集群前部署 SLB(如阿里云 SLB、Nginx 等),此時客戶端只需配置 SLB 的地址(如
<font style="color:rgb(0, 0, 0);">nacos-slb.com:80,DNS會將該域名轉為實際上SLB的地址</font>
),由 SLB 負責分發流量到后端 Nacos 節點。
1. DNS(域名系統)的作用
當 Spring Cloud 應用(客戶端)需要訪問 Nacos 集群時,首先會通過 DNS 解析 nacos-slb.com
這個域名。
- 作用:DNS 負責將 “易記的域名”(如
nacos-slb.com
)轉換為 SLB(負載均衡器)的 IP 地址。這樣客戶端無需記住復雜的 SLB IP,只需通過域名即可發起訪問,同時也便于后續 SLB IP 變更時,只需修改 DNS 解析記錄,無需修改客戶端配置。
2. SLB(負載均衡器)的作用
客戶端通過 DNS 拿到 SLB 的 IP 后,會向 SLB 發起請求。
- 作用:SLB 接收客戶端請求后,會按照預設的負載均衡策略(如輪詢、權重等),將流量分發到后端的多個 Nacos 節點(比如部署在不同服務器上的 Nacos 實例)。這樣既避免了單臺 Nacos 節點因流量過大而故障,又能在某臺 Nacos 節點宕機時,自動將流量切換到其他健康節點,保障 Nacos 集群的高可用性。
3. 整體流程示例
假設客戶端要從 Nacos 拉取配置:
- 客戶端代碼中配置的是 Nacos 相關地址為
nacos-slb.com:80
(通過域名訪問 SLB)。 - 客戶端發起請求時,先向 DNS 服務器查詢
nacos-slb.com
對應的 IP,DNS 返回 SLB 的 IP(比如192.168.1.100
)。 - 客戶端向
192.168.1.100:80
(SLB)發起請求。 - SLB 將請求轉發到后端健康的 Nacos 節點(比如
10.0.0.1:8848
)。 - Nacos 節點處理請求,返回配置數據給客戶端。
通過 DNS + SLB + Nacos 集群的組合,既實現了域名的便捷訪問與解耦(DNS 負責域名解析),又實現了流量的負載均衡與高可用(SLB 負責分發和故障轉移),保障了生產環境中 Nacos 服務的穩定運行。
搭建集群
在三個nacos中,cluster.conf都得改為:填充對應的要作為集群節點的端口號和ip
使用:
在springcloud中的server-addr:多個節點用 , 隔開即可
spring:application:name: config1 # 應用名稱,會作為默認dataId的一部分(默認格式:${name}-${profile}.${extension})cloud:nacos:config:server-addr: 127.0.0.1:8860,127.0.0.1:8861,127.0.0.1:8862 # 集群地址
Windows 系統 Nacos 單機 / 集群操作指南
Nacos 默認使用嵌入式數據庫(Derby)存儲數據,僅適合測試;生產 / 開發環境需配置外部數據庫(以 MySQL 為例),避免數據丟失和集群數據不一致。以下在原有操作基礎上,補充外部數據庫連接步驟。
一、單機模式操作步驟
1. 前置準備:創建 MySQL 數據庫
- 打開 MySQL 客戶端(如 Navicat、MySQL Workbench),執行以下 SQL 創建 Nacos 專用數據庫(默認庫名
<font style="color:rgb(0, 0, 0);">nacos_config</font>
,可自定義):
CREATE DATABASE IF NOT EXISTS nacos_config CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 進入
<font style="color:rgb(0, 0, 0);">nacos_config</font>
數據庫,執行 Nacos 自帶的數據庫腳本:
腳本路徑:<font style="color:rgb(0, 0, 0);">Nacos 安裝目錄/conf/nacos-mysql.sql</font>
(直接復制腳本內容到 MySQL 客戶端執行,會自動創建表結構和初始化數據)。
2. 配置外部數據庫連接
- 進入 Nacos 安裝目錄的
<font style="color:rgb(0, 0, 0);">conf</font>
文件夾:cmd
cd D:\nacos\conf
- 用文本編輯器打開
<font style="color:rgb(0, 0, 0);">application.properties</font>
,添加 MySQL 連接配置(放在鑒權配置之前或之后均可):properties
# 1. 啟用外部數據庫(禁用嵌入式 Derby)
spring.datasource.platform=mysql
# 2. 配置 MySQL 數據源數量(單 MySQL 實例填 1)
db.num=1
# 3. MySQL 數據庫連接地址(替換為你的 MySQL IP、端口、庫名)
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
# 4. MySQL 賬號(替換為你的 MySQL 用戶名)
db.user.0=root
# 5. MySQL 密碼(替換為你的 MySQL 密碼)
db.password.0=123456
3. 配置鑒權(Nacos 3.0+ 必需)
- 繼續在
<font style="color:rgb(0, 0, 0);">application.properties</font>
中添加鑒權密鑰(至少 32 個字符):properties
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
- 保存文件,數據庫和鑒權配置完成。
4. 啟動 Nacos 單機版
- 進入
<font style="color:rgb(0, 0, 0);">bin</font>
目錄:cmd
cd D:\nacos\bin
- 啟動單機模式(此時數據會存儲到 MySQL,而非嵌入式數據庫):cmd
startup.cmd -m standalone
- 驗證:訪問
<font style="color:rgb(0, 0, 0);">http://localhost:8848/nacos</font>
,登錄后在「配置管理」添加配置,再到 MySQL 的<font style="color:rgb(0, 0, 0);">nacos_config</font>
庫的<font style="color:rgb(0, 0, 0);">config_info</font>
表中,可看到新增的配置數據,說明數據庫連接成功。
5. 關閉、查看狀態、其他操作(同之前)
- 關閉:啟動窗口按
<font style="color:rgb(0, 0, 0);">Ctrl + C</font>
并輸入<font style="color:rgb(0, 0, 0);">Y</font>
,或另開 Cmd 執行<font style="color:rgb(0, 0, 0);">shutdown.cmd</font>
。 - 查看狀態:檢查端口
<font style="color:rgb(0, 0, 0);">netstat -ano | findstr "8848"</font>
,查看進程<font style="color:rgb(0, 0, 0);">tasklist | findstr "java"</font>
。 - 修改端口 / 清理緩存:同原有步驟(清理緩存不影響 MySQL 中的數據)。
二、集群模式操作步驟
集群模式下,所有節點需連接同一個 MySQL 數據庫(確保數據一致性),步驟如下:
1. 前置準備
- 創建 MySQL 數據庫:同單機模式步驟 1(僅需創建 1 個
<font style="color:rgb(0, 0, 0);">nacos_config</font>
庫,所有節點共用)。 - 復制 Nacos 安裝包:復制 Nacos 目錄為
<font style="color:rgb(0, 0, 0);">nacos-node1</font>
、<font style="color:rgb(0, 0, 0);">nacos-node2</font>
、<font style="color:rgb(0, 0, 0);">nacos-node3</font>
(3 個節點)。
2. 配置各節點(以 <font style="color:rgb(0, 0, 0);">nacos-node1</font>
為例,其他節點同理)
(1)配置外部數據庫連接
- 進入
<font style="color:rgb(0, 0, 0);">nacos-node1\conf</font>
目錄,打開<font style="color:rgb(0, 0, 0);">application.properties</font>
,添加 MySQL 配置(所有節點的數據庫配置完全一致):properties
# 啟用外部數據庫
spring.datasource.platform=mysql
# 數據源數量(單 MySQL 實例填 1)
db.num=1
# MySQL 連接地址(替換為你的 MySQL 信息)
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
# MySQL 賬號
db.user.0=root
# MySQL 密碼
db.password.0=123456
(2)配置鑒權
- 繼續在
<font style="color:rgb(0, 0, 0);">application.properties</font>
中添加統一鑒權密鑰(所有節點的密鑰必須相同):properties
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
(3)修改節點端口
- 在
<font style="color:rgb(0, 0, 0);">application.properties</font>
中設置當前節點的端口(3 個節點端口不同):properties
server.port=8848 # node1 用 8848,node2 用 8849,node3 用 8850
(4)配置集群節點列表
- 在
<font style="color:rgb(0, 0, 0);">nacos-node1\conf</font>
目錄下,將<font style="color:rgb(0, 0, 0);">cluster.conf.example</font>
重命名為<font style="color:rgb(0, 0, 0);">cluster.conf</font>
,并修改內容為所有節點的 IP + 端口:plaintext
127.0.0.1:8848
127.0.0.1:8849
127.0.0.1:8850
- 注意:
<font style="color:rgb(0, 0, 0);">nacos-node2</font>
、<font style="color:rgb(0, 0, 0);">nacos-node3</font>
的<font style="color:rgb(0, 0, 0);">cluster.conf</font>
內容與<font style="color:rgb(0, 0, 0);">node1</font>
完全一致(確保所有節點知道集群內其他節點)。
3. 啟動集群
- 分別打開 3 個 Cmd 窗口,啟動每個節點:cmd
# 啟動 node1
cd D:\nacos-node1\bin
startup.cmd# 啟動 node2
cd D:\nacos-node2\bin
startup.cmd# 啟動 node3
cd D:\nacos-node3\bin
startup.cmd
4. 驗證集群與數據庫
- 檢查端口:執行以下命令,確認 8848、8849、8850 端口均已占用:cmd
netstat -ano | findstr "8848 8849 8850"
- 驗證集群狀態:訪問任意節點控制臺(如
<font style="color:rgb(0, 0, 0);">http://localhost:8848/nacos</font>
),登錄后進入「集群管理」→「節點列表」,3 個節點均顯示「健康」。 - 驗證數據庫:在控制臺添加一條配置(如 DataID 為
<font style="color:rgb(0, 0, 0);">test-cluster</font>
),然后到 MySQL 的<font style="color:rgb(0, 0, 0);">nacos_config.config_info</font>
表中,可看到該配置數據;再登錄其他節點控制臺,也能看到這條配置,說明集群數據通過 MySQL 保持一致。
5. 關閉集群(同之前)
- 分別在 3 個 Cmd 窗口執行關閉命令:cmd
# 關閉 node1
cd D:\nacos-node1\bin
shutdown.cmd# 關閉 node2
cd D:\nacos-node2\bin
shutdown.cmd# 關閉 node3
cd D:\nacos-node3\bin
shutdown.cmd
三、關鍵說明
- 數據庫版本要求:Nacos 支持 MySQL 5.7+ 或 8.0+,若使用 MySQL 8.0,需確保
<font style="color:rgb(0, 0, 0);">application.properties</font>
中<font style="color:rgb(0, 0, 0);">db.url.0</font>
已添加<font style="color:rgb(0, 0, 0);">serverTimezone=UTC</font>
(避免時區報錯)。 - 集群數據一致性:所有節點必須連接同一個 MySQL 數據庫,否則會出現配置 / 服務數據不一致。
- 密碼特殊字符處理:若 MySQL 密碼含特殊字符(如
<font style="color:rgb(0, 0, 0);">!@#$</font>
),需在<font style="color:rgb(0, 0, 0);">db.password.0</font>
中用雙引號包裹(如<font style="color:rgb(0, 0, 0);">db.password.0="123!@#"</font>
)。 - 嵌入式數據庫禁用:配置
<font style="color:rgb(0, 0, 0);">spring.datasource.platform=mysql</font>
后,Nacos 會自動禁用 Derby,無需額外操作。