③ Nacos 【服務中心和配置中心】
2.1 Nacos 簡介和安裝
前四個字母分别為Naming和Configuration的前兩個字母,最後的s為Service
Nacos是什麼
專業術語:
一個更易于建構雲原生應用的動态服務發現、配置管理和服務管理平台。
Nacos:Dynamic Naming and Configuration Service
簡單的說:
Nacos就是 注冊中心 + 配置中心的組合
Nacos = Eureka + Config + Bus
作用:能替代eureka做服務注冊中心、能替代config做服務配置中心
官方文檔: https://nacos.io/zh-cn/index.html
學習手冊:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_config
下載下傳位址: Release 1.4.2 (Apr 29th, 2021) · alibaba/nacos (github.com)
各注冊中心的對比
安裝
- 先從官網下載下傳Nacos
- 解壓安裝包,直接運作bin目錄下的startup.cmd
- 如果啟動失敗就使用 startup.cmd -m standalone 指令啟動, 因為預設啟動是cluster模式,我們帶參數改為單機版啟動就行
- 運作成功後通路http://localhost:8848/nacos
- 登入頁面的賬号密碼全為nacos
2.2 Nacos作為服務注冊中心
2.2.1 基于Nacos的服務提供者
- 建立項目父項目springcloud_alibaba
- 導入父依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.cvzhanshi</groupId>
<artifactId>springcloud_alibaba</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.18.12</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<!--springCloud的依賴-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.2.1.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SpringBoot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--資料庫-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<!--SpringBoot 啟動器-->
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--日志測試~-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 建立子產品springcloudalibaba-provider-payment9001服務提供者
- 導入依賴
<!--本pom.xml引入nacos-->
<dependencies>
<!--springcloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 編寫配置檔案application.yaml
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos位址
management:
endpoints:
web:
exposure:
include: '*' #監控
- 主啟動類
/**
* @author cVzhanshi
* @create 2021-07-01 15:15
*/
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class,args);
}
}
- 業務類
/**
* @author cVzhanshi
* @create 2021-07-01 15:16
*/
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id){
return "nacos registry,serverPort: "+ serverPort+"\t id"+id;
}
}
- 運作nacos和9001子產品
- 測試業務
- 添加子產品9002和9001除了端口其他一樣,為了測試負載均衡,啟動9002後就發現一個服務下有兩個執行個體
2.2.2 基于Nacos的服務消費者
- 建立服務消費者子產品springcloud-consumer-nacos-order83,導入依賴
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 編寫配置檔案
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
#消費者将要去通路的微服務名稱(成功注冊進nacos的微服務提供者),在這配置了通路的服務,業務類就不用在定義常量了
service-url:
nacos-user-service: http://nacos-payment-provider
- 主啟動類
- 因為nacos自動內建了Ribbon,是以配置restTemplate
/**
* @author cVzhanshi
* @create 2021-07-01 16:37
*/
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced//負載均衡
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- 主啟動類
/**
* @author cVzhanshi
* @create 2021-07-03 16:22
*/
@SpringBootApplication
public class OrderNacosMain83 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain83.class,args);
}
}
- 業務類
/**
* @author cVzhanshi
* @create 2021-07-01 16:39
*/
@RestController
public class OrderNacosController {
/*
因為在yaml中配置了service-url.nacos-user-service,
這裡不需要再定義要通路微服務名常量,而是通過boot直接讀出來
*/
@Value("${service-url.nacos-user-service}")
private String serverURL;
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id){
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
- 測試
發現一個消費者兩個服務執行個體
2.2.3 服務注冊中心的對比
Nacos 支援AP 和 CP模式的轉換
C是所有節點在同一時間看到的資料是一緻的;而A的定義是所有的請求都會受到響應。
何時選擇使用何種模式?
一般來說,如果不需要存儲服務級别的資訊且服務執行個體是通過nacos-client注冊,并能夠保持心跳上報,那麼就可以選擇AP模式。目前主流的服務如SpringCloud和Dubbo服務,都适用與AP模式,AP模式為了服務的可能性而減弱了一緻性,是以AP模式下隻支援注冊臨時執行個體。
如果需要在服務級别編輯或存儲配置資訊,那麼CP是必須,K8S服務和DNS服務則适用于CP模式。CP模式下則支援注冊持久化執行個體,此時則是以Raft協定為叢集運作模式,該模式下注冊執行個體之前必須先注冊服務,如果服務不出存在,則會傳回錯誤。
用下面指令切換
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP
2.3 Nacos作為服務配置中心
2.3.1 基礎配置
- 建立子產品springcloudalibaba-config-nacos-client3377,導入依賴
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 編寫配置檔案 bootstrap.yaml 和 application.yaml
bootstrap.yaml
#bootstrap.xml
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服務注冊中心位址
config:
server-addr: localhost:8848 #Nacos作為配置中心位址
file-extension: yaml #指定yaml格式的配置
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file.extension}
# nacos-config-client-dev.yaml
application.yaml
#application.yml
spring:
profiles:
active: dev #開發環境
- 主啟動類
/**
* @author cVzhanshi
* @create 2021-07-03 16:52
*/
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class,args);
}
}
- 在Nacos中添加配置資訊
Nacos中的比對規則
p r e f i x − {prefix}- prefix−{spring.profiles.active}.${file-extension}
預設為
prefix
的值,也可以通過配置項
spring.application.name
來配置。
spring.cloud.nacos.config.prefix
即為目前環境對應的 profile。 注意:當
spring.profiles.active
為空時,對應的連接配接符
spring.profiles.active
也将不存在,dataId 的拼接格式變成
-
${prefix}.${file-extension}
為配置内容的資料格式,可以通過配置項
file-exetension
來配置。目前隻支援
spring.cloud.nacos.config.file-extension
和
properties
類型。
yaml
- 運作測試 ,通路 http://localhost:3377/config/info
- 修改nacos中的配置,用戶端不重新啟動,測試實時更新
2.3.2 分類配置
問題1:
實際開發中,通常一個系統會準備dev開發環境、test測試環境、prod生産環境,如何保證指定環境啟動時服務能正确讀取到Nacos上相應環境的配置檔案呢?
問題2:
一個大型分布式微服務系統會有很多微服務子項目,每個微服務項目又會有相應的開發環境、測試環境、預發環境、正式環境…那怎麼對這些微服務配置進行管理呢?
Namespace + Group + Data ID三者關系 :
類似Java中的package名和類名
最外層的namespace是可以用于區分部署環境的,Group和DataID邏輯上區分兩個目标對象
預設情況:
Namespace=public,Group=DEFAULT_GROUP,預設Cluster是DEFAULT
Nacos預設的命名空間是public,Namespace主要用來實作隔離
比方說我們現在有三個環境:開發、測試、生産環境,我們就可以建立三個Namespace,不同的Namespace之間是隔離的。
Group預設是DEFAULT_GROUP,Group可以把不同的微服務劃分到同一個分組裡面去
Service就是微服務,一個Service可以包含多個Cluster(叢集),Nacos預設Cluster是DEFAULT,Cluster是對指定微服務的一個虛拟劃分
比方說為了容災,将Service微服務分别部署在了杭州機房和廣州機房,這時就可以給杭州機房的Service微服務起一個叢集名稱(HZ)給廣州機房的Service微服務起一個叢集名稱(GZ),還可以盡量讓同一個機房的微服務互相調用,以提升性能。
最後是Instance,就是微服務的執行個體。
三種方案加載配置
- DataID方案配置:指定spring.profile.active和配置檔案的DataID來使不同環境下讀取不同的配置
- 預設空間 + 預設分組 + 建立dev和test兩個DataID
- 通過spring.profile.active屬性就能進行多環境下配置檔案的讀取
- Group方案:通過Group實作環境區分
- 建立兩個分組
- bootstrap 和 application配置修改
bootstrap
#bootstrap.yaml
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服務注冊中心位址
config:
server-addr: localhost:8848 #Nacos作為配置中心位址
file-extension: yaml #指定yaml格式的配置
group: DEV_GROUP
application
#application.yml
spring:
profiles:
active: info #開發環境
- 測試
- 修改分組,再測試
- Namespace方案:
- 建立命名空間
- 在建立的命名空間中建立配置檔案
- 修改配置檔案
bootstrap.yaml
#bootstrap.xml
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服務注冊中心位址
config:
server-addr: localhost:8848 #Nacos作為配置中心位址
file-extension: yaml #指定yaml格式的配置
group: TEST_GROUP
namespace: d5105f8e-f24f-4cd8-a6a4-b3c88bdd824e
application.yaml
#application.yml
spring:
profiles:
active: dev #開發環境
- 測試
由此我們可以通過配置檔案中的namespace、group、active來選擇要讀取的nacos中的配置檔案
2.4 Nacos 叢集和持久化
2.4.1 叢集和持久化的簡介
自己準備搭建叢集的結構圖
預設Nacos使用嵌入式資料庫(derby)實作資料的存儲。是以,如果啟動多個預設配置下的Nacos節點,資料存儲是存在一緻性問題的。
為了解決這個問題,Nacos采用了集中式存儲的方式來支援叢集化部署,目前隻支援Mysql的存儲
Nacos支援三種部署模式
https://nacos.io/zh-cn/docs/deployment.html
- 單機模式:用于測試和單機試用
- 叢集模式:用于生産環境,確定高可用
- 多叢集模式:用于多資料中心場景
2.4.2 持久化
Nacos預設自帶的是嵌入式資料庫derby
derby到mysql切換配置步驟:
- nacos-server-1.1.4\nacos\conf 目錄下執行sql腳本
nacos-mysql.sql
- nacos-server-1.1.4\nacos\conf 目錄下找到
,添加配置:application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=xxx
db.password=xxx
2.4.3 Linux搭建Nacos叢集
Linux安裝nacos
- 在官網上下載下傳好安裝包,上傳到linux上
- 解壓安裝包
tar -zxvf nacos-server-1.1.4.tar.gz
- 把解壓出來的檔案夾複制到/mynacos檔案夾中(個人習慣,不動源檔案)
- 進入/mynacos/nacos/bin目錄中,備份啟動檔案
重點:叢集的配置
- Linux伺服器上MySQL資料庫配置
在伺服器的mysql,建立資料庫nacos_config,如何在nacos解壓檔案的conf下有sql腳本nacos-mysql.sql,執行即可
- application.properties的配置
先備份application.propertiesvim這個檔案,添加以下内容cp application.properties application.properties.bf
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=root db.password.0=123456
- Linux伺服器上nacos的叢集配置cluster. conf
老套路,先備份檔案内容修改如下,其中檔案中的ip是hostname -i 能識别的ipcp cluster.conf.example cluster.conf
192.168.242.110:3333 192.168.242.110:4444 192.168.242.110:5555
- 編輯Nacos的啟動腳本startup.sh,使它能夠接受不同的啟動端口
修改内容如下
- Nginx的配置,由它作為負載均衡器
修改内容如下,路徑用whereis nginx檢視,其中的conf/nginx.conf
測試
- 先啟動3個nacaos
查詢有三個nacos啟動成功
- 啟動nginx
./nginx -c /usr/local/nginx/conf/nginx.conf
- 浏覽器通路nacos
- 登入進去建立一個配置然後查詢資料庫看看是否有記錄添加
- 項目中配置nacos,看看項目服務能不能注冊進入nacos叢集中
叢集搭建完成