下面將研究如下幾個問題: java
7.Nacos集羣部署mysql
這張圖說明了nacos是一個單獨的服務器, 用戶修改或者發佈配置信息, 會通知下游的服務器. 下游的服務器也能夠根據必定的規則讀取配置中心的配置信息.web
讓nacos成爲spring cloud集羣的一部分spring
啓動nacos服務sql
將nacos納爲spring cloud微服務的一部分docker
下面驗證服務的可用性數據庫
./startup.sh -m standalonebootstrap
注意: 這裏必定要單機模式啓動, 默認是集羣模式, 咱們如今沒有在集羣中, 會報異常.api
nacos是一個服務, 他對外也提供了不少接口, 其中一個是添加配置的接口. 咱們模擬這個接口進行配置: 緩存
curl -X POST "http://localhost:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"
看到返回結果是true. 而後刷新控制檯, 能夠看到以下
curl -X GET "http://localhost:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
這個命令就是獲取配置
獲取helloworld內容
咱們把配置信息添加到nacos, 那麼,他是如何保存的呢? nacos某一個默認的自帶數據庫, 這個數據庫不方便操做和查找. 所以咱們將其替換爲本身的mysql數據庫
1. 準備一個mysql數據庫
由於mysql比較大, 因此,我使用的是docker安裝的mysql
下載mysql
docker pull mysql:5.7.15
啓動mysql
docker run -p 3306:3306 --name MySQLDocker -v $PWD/conf/my.cnf:/etc/mysql/conf.d/my.cnf -v $PWD/logs:/var/log/mysql -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.15
2. 建立一個nacos_config的數據庫
3. 初始化nacos_config表結構
在這裏找到配置文件: ${nacosHome}/conf/nacos-mysql.
4. 修改application.properties配置文件
而後從新啓動.
在執行上面的寫配置
數據庫裏生成了一條配置信息:
1. 在控制檯添加配置
Data ID: nacos-simple-demo.yaml Group: DEFAULT_GROUP 配置格式: YAML 配置內容: common config: something
將以上信息在控制檯配置好了
以上就是在nacos服務端建好了配置信息
2. 模擬nacos客戶端--獲取nacos服務端配置
public class DemoTest { public static void main(String[] args) throws NacosException { String dataId = "test.demo.yml"; String group = "DEFAULT_GROUP"; String serverAddr = "localhost:8848"; Properties properties = new Properties(); properties.setProperty("serverAddr", serverAddr); // 和nacos服務創建鏈接 ConfigService configService = NacosFactory.createConfigService(properties); String config = configService.getConfig(dataId, group, 10); System.out.println(config); } }
ok, 就能夠獲取nacos的配置信息了
對於nacos配置管理, 經過namespace, group, dataId可以定位到一個配置集.
nacos的配置管理模型包含三部分: namespace, group, service/data Id. 經過配置管理模型, 咱們能夠定位到所須要的配置文件
其中service/data Id中. server是服務發現, dataId是配置管理.
1. 配置集(DataId)
配置集就是上圖的DataId
在系統中, 一般一個配置文件, 就是一個配置集. 一個配置集能夠包含系統的各類配置信息. 例如:一個配置集可能包含系統的數據源、鏈接池, 日誌等級的配置信息。每一個配置集均可以定義一個有意義的名稱, 就是配置集的Id, 即Data Id
2. 配置項
配置集中包含的一個個配置內容, 就是配置項. 他表明具體的可配置的參數. 一般以key=value的形式存在.
3. 配置分組(Group)
配置分組就是上圖中的Group. 配置分組是對配置集進行分組. 經過一個有意義的字符串(如: buy, trade)來表示. 不一樣的配置分組下能夠有相同的配置集(Data ID). 當您在nacos上建立一個配置的時候, 若是未填寫配置分組的名稱, 則採用默認名稱DEFAULT_GROUP.
配置分組的常見場景有: 可用於區分不一樣的項目或應用. 例如: 學生管理系統的配置集能夠定義一個group爲:STUDENT_GROUP.
4 命名空間(Namespace)
命名空間(namespace)可用於對不一樣的環境進行配置隔離. 例如: 能夠隔離開發環境, 測試環境, 生成環境. 由於他們的配置可能各不相同. 或者是隔離不一樣的用戶, 不一樣的開發人員使用同一個nacos管理各自的配置, 可經過namespace進行隔離. 不一樣的命名空間下, 能夠存在相同名稱的配置分組(Group)或配置項(Data Id)
最佳實踐
一般咱們能夠這樣定義namespace, group, dataid
Namespace: 表明不一樣的環境, 如: 開發、測試, 生產等
Group: 能夠表明某個項目, 如XX醫療項目, XX電商項目
結合已有的項目, 進行分析
咱們先來回顧一下上面的客戶端實現. 在上面的客戶端實現中,咱們是沒有定義命名空間的. 那麼他會採用默認的命名空間public.
按照環境來設計namespace: 開發, 測試, 生產
這樣不一樣的環境的配置是相互隔離開的, 互不影響
建立命名空間
界面操做比較簡單,不都說了
下面我建立了4個命名空間. 其中public和dev都有一個Data Id叫作test.demo.yml. 我要經過程序代碼獲取dev下的test.demo.yml配置文件.
模擬客戶端獲取nacos的命名空間爲dev下的配置信息:
package com.lxl.org; import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.exception.NacosException; import java.util.Properties; public class DemoTest { public static void main(String[] args) throws NacosException, InterruptedException { String dataId = "test.demo.yml"; // 注意: 這裏填的是命名空間的id String namespace = "dev"; String group = "DEFAULT_GROUP"; String serverAddr = "localhost:8848"; Properties properties = new Properties(); properties.setProperty("serverAddr", serverAddr); properties.setProperty("namespace", namespace); // 和nacos服務創建鏈接 ConfigService configService = NacosFactory.createConfigService(properties); String config = configService.getConfig(dataId, group, 10); System.out.println(config); Thread.sleep(1000); } }
須要指定要獲取的配置是哪一個命名空間下面的.
歷史版本這裏就說一點, 那就是能夠回滾. 點擊回滾, 就回滾到了某個版本的配置
想要監聽開發環境下, 某個配置文件. 則課一下監聽查詢中查看哪些配置文件被監聽了.
好比: 咱們寫一個demo, 監聽dev下的test.demo.yaml配置文件
public static void main(String[] args) throws NacosException, InterruptedException { String dataId = "test.demo.yml"; // 注意: 這裏填的是命名空間的id String namespace = "a127e7f7-e37e-48fb-9968-cca7ef7c9f26"; String group = "DEFAULT_GROUP"; String serverAddr = "localhost:8848"; Properties properties = new Properties(); properties.setProperty("serverAddr", serverAddr); properties.setProperty("namespace", namespace); // 和nacos服務創建鏈接 ConfigService configService = NacosFactory.createConfigService(properties); String config = configService.getConfig(dataId, group, 10); System.out.println(config); configService.addListener(dataId, group, new Listener() { @Override public Executor getExecutor() { return null; } @Override public void receiveConfigInfo(String s) { // 接收監聽到的返回的配置信息 System.out.println(s); } }); Thread.sleep(1000000); }
寫一個監聽程序, 不停的進行監聽. 一旦有配置發生變化, 馬上就能夠通知過來.
nacos支持簡單的登陸功能, 默認的用戶名/密碼是: nacos/nacos.
修改默認用戶名和密碼的方法:
經過看源碼能夠知道, nacos用戶加密使用的是BCrypt加密的方式. 所以,咱們能夠模擬一個BCrypt方法進行修改密碼
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>5.1.4.RELEASE</version> </dependency>
而後寫一個修改密碼的方法
package com.lxl.org;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class PasswordHandler {
public static void main(String[] args) {
String encode = new BCryptPasswordEncoder().encode("123");
System.out.println(encode);
}
}
輸出結果替換數據庫中的密碼便可
$2a$10$LW/6RKgceuALErDPcU8THOT5V1Ajc98jgo6N38oOX0Tvmce39hP4a
新加用戶, 須要設置用戶的用戶名和角色
insert into users(username, password, enabled) VALUES ("lxl", "$2a$10$LW/6RKgceuALErDPcU8THOT5V1Ajc98jgo6N38oOX0Tvmce39hP4a", 1);
insert into roles(username, role) VALUES ('lxl', 'ROLE_ADMIN')
也能夠在控制檯修改 ### **六. Nacos配置管理應用於分佈式系統** 下圖展現了nacos集中管理多個配置服務的流程 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200355817.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) 1. 用戶經過nacos 服務的控制檯對配置文件進行集中管理 2. 各服務統一從nacos中獲取各自的配置, 並監聽配置的變化. ---------------------------------------- ## 1. 模擬兩個微服務請求一個註冊中心的場景. **1. 在dev環境下, 新建兩個配置文件. server1, server2** ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200502468.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) **2. 建立一個簡單的微服務架構. 採用spring cloud微服務架構.** 建立一個parent工程, 引入公共的配置. 在建立兩個微服務server1, server2 建立一個parent maven工程, 引入maven包
<dependencyManagement>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
建立一個service1. 而後添加nacos的maven管理. 在添加bootstrap.yml配置文件, 最後增長啓動類
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
配置文件bootstrap.yml. 這裏須要注意的是默認查找的data Id是應用面+擴展名
server:
port: 56010
spring:
application:
name: service1
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
namespace: dev
group: TEST_GROUP
最後增長啓動類, 裏面直接定義了一個controller, 獲取配置信息
package com.lxl.www.service1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplicationbr/>@RestController
public class BootStrapApplication {
public static void main(String[] args) {
SpringApplication.run(BootStrapApplication.class, args);
}
/** * 採用註解的方式讀取nacos配置信息 */ @Value("${common.config}") private String config1; /** * 定義一個controller */ @GetMapping(value = "/config") public String getNacosConfig() { return config1; }
}
service2也是如此.
注意: nacos發佈的時候, 要打開日誌文件, 看看是否發佈成功. 若是報異常, 可能發佈不成功. 項目獲取配置文件失敗
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200614155.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) **這裏客戶端使用的是阿里提供的nacos客戶端:** spring-cloud-starter-alibaba-nacos-config **存在的問題:** 當使用spring的註解@Value的時候, 咱們發現, 在配置中心修改了配置文件的內容, 可是經過註解讀取出來的內容沒變. 這是什麼願意鬧呢?其實, 配置文件修改了內容之後, 他是通知了服務端的, 之因此沒改, 是由於@Value屬性的緣由, 他應該是有緩存了. 那麼若是想動態獲取修改後的配置文件, 有兩種方式: **方式一: 使用properties.** 獲取配置的方式, 修改以下:
@Autowired
private ConfigurableApplicationContext applicationContext;
/** * 定義一個controller */ @GetMapping(value = "/config") public String getNacosConfig() { return applicationContext.getEnvironment().getProperty("common.config"); }
**方式二: @NacosValue** 注意事項: - nacos的配置信息要寫在bootstrap.yml中. 讓其配置信息優先加載. (bootstrap.yml加載的時間要比application.yml早) ## **2. 擴展DataId, 多配置處理** 若是有多個配置文件, 咱們可使用擴展配置的方式, 添加多個配置文件
擴展配置id, 第一個擴展的配置id
ext-config[0]:
data-id: ext-config-common01.yml
ext-config[1]:
data-id: ext-config-common02.yml
group: GLOBAL_GROUP
ext-config[2]:
data-id: ext-config-common03.yml
group: REFRESH_GROUP
refresh: true #配置修改, 是否刷新
第一個配置, 只有一個data-id. 沒有group, 採用默認的DEFAULT_GROUP. 第二個擴展配置. 定義了一個GLOBAL_GROUP. 全局配置 第三個擴展配置: 定義爲一個自動刷新的GROUP, 並設置自動刷新屬性爲true 接下來咱們在控制檯添加這三個文件 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200800883.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200808501.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200817292.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) 修改接口獲取配置信息
/** * 定義一個controller */ @GetMapping(value = "/config") public String getNacosConfig() { String p1 = applicationContext.getEnvironment().getProperty("common.config"); String p2 = applicationContext.getEnvironment().getProperty("common.ext1"); String p3 = applicationContext.getEnvironment().getProperty("common.ext2"); String p4 = applicationContext.getEnvironment().getProperty("common.ext3"); return p1 + "+" + p2 + "+" + p3 + "+" + p4; }
咱們能夠看到打印出來的效果 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126200925413.png) 這時, 在控制檯修改配置文件, 咱們發現common.config會改變. common.ext3會改變. 其餘兩個不會自動更新 總結: 默認配置是能夠自動刷新的. 在擴展配置中, 只有增長了屬性refresh:true, 纔會自動刷新 ## 3. 共享Data Id 咱們能夠設置共享data id, 設置方法以下: ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/2021012620094390.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) 設置共享的data id. 咱們設置了三個文件. 啓動項目, 運行結果以下 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/202101262009549.png) 咱們發現, 有兩個是null. 爲何是null呢? 由於使用這種方式配置, 只能第一個文件生效, 所以, 若是想要配置多個擴展文件, 還要使用擴展dataId的方式. ## **4. 配置Data Id的優先級** **目前有三種設置Data Id的方式** - 默認的data id. 項目名+擴展名的方式. - 使用ext-config[0] 設置擴展配置 - 使用shared-dataids: 設置共享配置. 那麼, 他們三個的優先級是什麼樣的呢? **默認配置 > ext-config > shared-dataids** 若是有多個ext-config擴展配置, 誰的優先級高呢? n的個數越大, 優先級越高..... **ext-config[n] > ext-config[2] > ext-config[1] > ext-config[0]** ## 5. 關閉Nacos配置 若是不想要使用nacos配置了, 那麼可使之enable屬性爲false # 七. Nacos集羣部署 一般咱們在生成環境不可能只有一臺nacos. 爲了保證高可用性, 咱們會配置多臺nacos. 要求: 配置3臺或以上nacos服務 下面咱們來模擬三臺nacos服務集羣 第一步: 解壓三個nacos服務 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126201054158.png) 第二步: 修改配置文件 1. 修改端口號. 分別設置爲8848, 8849, 8850 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126201101885.png) ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126201105688.png) ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126201111343.png) **2. 添加本地服務的ip地址** 給三個服務都增長下面這個配置內容: 設置本機的ip地址 >nacos.inetutils.ip-address=127.0.0.1 **3. 設置三個nacos的集羣關係** 修改cluster.conf.example文件爲cluster.conf 並在裏面添加以下內容 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/2021012620113248.png) **第四步: 啓動三臺服務器. 以集羣的模式啓動** ./start.sh -m cluster 而後, 在控制他查看集羣, 有一臺主, 兩臺從 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126201144544.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) **第五步 在項目中配置nacos集羣** ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20210126201156835.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDgyNjEyMw==,size_16,color_FFFFFF,t_70) 注意: 多個配置之間不能帶空格. 重啓項目. 訪問接口返回內容 ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/202101262012087.png) 這裏面, 咱們能夠停掉任何一臺nacos服務. 只要還有一個能運行, 服務就能夠訪問通