【SpringCloud】SpringCloud Alibaba Nacos服務註冊和配置中心
SpringCloud Alibaba Nacos服務註冊和配置中心
Nacos簡介
為什麼叫Nacos
前四個字母為Nameing和Configuration的前兩個字母,最後的s為Service
是什麼
- 一個更易於構建原生應用的動態服務發現、配置管理和服務管理平臺
- Nacos:Dynamic Naming and Configuration Service
Nacos就是註冊中心+配置中心的組合
等價於:Nacos=Eureka+Config+Bus
能幹嘛
- 替代Eureka做服務註冊中心
- 替代Config做服務配置中心
去哪下
https://github.com/alibaba/Nacos
官網文件
- https://nacos.io/zh-cn/
- https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_discovery
各種註冊中心對比
服務註冊與發現框架 | CAP模型 | 控制檯管理 | 社群活躍度 |
---|---|---|---|
Eureka | AP | 支援 | 低(2.x版本閉源) |
Zookeeper | CP | 不支援 | 中 |
Consul | CP | 支援 | 高 |
Nacos | AP | 支援 | 高 |
據說Nacos在阿里巴巴內部有超過10萬的例項執行,已經過了類似雙十一等各種大型流量的考驗
安裝並執行Nacos
- 本地Java8+Maven環境已經ok
- 先從官網下載Nacos
- 解壓安裝包,直接執行bin目錄下的startup.cmd
命令執行成功後直接訪問http://localhost:8848/nacos
預設使用者名稱密碼都是nacos
結果頁面
Nacos作為服務註冊中心演示
官方文件
https://spring.io/projects/spring-cloud-alibaba
詳細說明文件
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_start_a_provider_application
基於Nacos的服務提供者
新建module
cloudalibaba-provider-payment9001
POM
父POM
<!--Spring cloud alibaba 2.1.0.RELEASE-->
<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>
本模組POM
<dependencies>
<!-- SpringCloud ailibaba 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.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
YML
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
management:
endpoints:
web:
exposure:
include: '*'
主啟動
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class,args);
}
}
業務類
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id) {
return "Hello Nacos Discovery: " + serverPort + "\t id: " + id;
}
}
測試
http://localhost:9001/payment/nacos/31
nacos控制檯
nacos服務註冊中心+服務提供者9001都ok了
為了下一章演示nacos叢集,參考9001新建9002
這裡如果名字取錯了還暴力刪除導致建立的工程沒有source標誌的,那是因為父工程的.idea檔案沒有更新,記得關掉專案刪除.idea,再重新匯入專案即可
cloudalibaba-provider-payment9002
取巧的方法是,直接拷貝虛擬埠對映(不建議,自己玩玩可以,因為還是同一個模組)
基於Nacos的服務消費者
新建Module
cloudalibaba-consumer-nacos-order83
POM
<dependencies>
<!-- SpringCloud ailibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency><!-- 引用自己定義的api通用包,可以使用Payment支付Entity -->
<groupId>com.eiletxie.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</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.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
為什麼Nacos支援負載均衡
nacos內建了 ribbon
YML
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
#消費者將去訪問的微服務名稱(註冊成功進nacos的微服務提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
主啟動
@SpringBootApplication
@EnableDiscoveryClient
public class OrderNacosMain83 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain83.class,args);
}
}
業務類
ApplicationContextConfig
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
OrderNacosController
@RestController
@Slf4j
public class OrderNacosController {
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping(value = "/consumer/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Integer id) {
return restTemplate.getForObject(serverURL + "/payment/nacos/" + id,String.class);
}
}
測試
http://localhost:83/consumer/payment/nacos/31
服務註冊中心對比
Nacos全景圖所示
Nacos和CAP
AP/CP切換
Nacos支援AP和CP模式的切換
C是所有節點在同一時間看到的資料是一致的; 而A的定義是所有的請求都會收到響應。
何時選擇使用何種模式?
一般來說,
如果不需要儲存服務級別的資訊且服務例項是通過nacos client註冊,井能夠保持心跳上報,那麼就可以選擇AP模式。當前主流的服務如Spring cloud和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'
Nacos作為服務配置中心演示
Nacos作為配置中心-基礎配置
cloudalibaba-config-nacos-client3377
POM
<dependencies>
<!-- nacos config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud ailibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency><!-- 引用自己定義的api通用包,可以使用Payment支付Entity -->
<groupId>com.eiletxie.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</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.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
YML
bootstrap
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格式配置
application
spring:
profiles:
active: dev #表示開發環境
why配置兩個
Nacos同springcloud-config-樣,在專案初始化時,要保證先從配置中心進行配置拉取,拉取配置之後,才能保證專案的正常啟動。
springboot中配置檔案的載入是存在優先順序順序的,bootstrap優先順序高於application
主啟動類
@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class,args);
}
}
業務類
ConfigClientController
@RestController
@RefreshScope // 支援Nacos的動態重新整理功能
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
@RefreshScope動態重新整理,忘了嗎?
在Nacos中新增配置資訊
Nacos中的匹配規則
理論
Nacos中的dataid的組成格式及與SpringBoot配置檔案中的匹配規則
官網
實操
配置新增
nacos-config-client-dev
Nacos介面配置對應
設定DataId
- 公式:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- prefix預設為spring.application.name的值
- spring.profile.active即為當前環境對應的profile,可以通過配置項spring.profile.active來配置。
- file-exetension為配置內容的資料格式,可以通過配置項speing.cloud.nacos.config.file-extension配置
- 小總結說明
歷史配置
- Nacos會記錄配置檔案的歷史版本預設保留30天,此外還有一件回滾功能
- 回滾
測試
- 啟動前需要在nacos客戶端-配置管理-配置管理欄目下有對應的yaml配置檔案
- 執行cloud-config-nacos-client3377的主啟動類
- 呼叫介面檢視配置資訊
http://localhost:3377/config/info
自帶動態重新整理
修改下Nacos中的yaml配置檔案,再次呼叫檢視配置的介面,就會發現配置已經重新整理
Nacos作為配置中心-分類配置
問題
多環境多專案管理
問題1:
實際開發中,通常-個系統會準備
dev開發環境
test測試環境
prod生產環境。
如何保證指定環境啟動時服務能正確讀取到Nacos上相應環境的配置檔案呢?
問題2:
一個大型分散式微服務系統會有很多微服務子專案,
每個微服務專案又都會有相應的開發環境、測試環境、預發環境、正式環境....
那怎麼對這些微服務配置進行管理呢?
Nacos的圖形化管理介面
配置管理
名稱空間
Namespace+group+data ID三者關係?為什麼這麼設計?
是什麼
類似Java裡面的package名和類名
最外層的namespace是可以用於區分部署環境的,Group和DatalD邏輯 上區分兩個目標物件。三者情況
預設情況:
Namespace= public, Group=DEFAULT_ GROUP,預設Cluster是DEFAULT
Nacos預設的名稱空間是public, Namespace主要用來實現隔離。
比方說我們現在有三個環境:開發、測試、生產環境,我們就可以建立E個Namespace, 不同的Namespace之間是隔離的。
Group預設是DEFAULT_ GROUP, Group可以把不同的微服務劃分到同一個分組裡面去
Service就是微服務; 一個Service可以包含多 個Cluster (叢集),Nacos預設Cluster是DEFAULT, Clyster是對指定微服務的一個虛擬劃分。
比方說為了容災,將Service微服務分別部署在了杭州機房和廣州機房,
這時就可以給杭州機房的Service微服務起一個叢集名稱(HZ),
給廣州機房的Service微服務起一個叢集名稱 (GZ) ,還可以儘量讓詞一個機房的微服務互相呼叫,以提升效能。
最後是Instance,就是微服務的例項。
Case
三種方案載入配置
DataID方案
指定spring.profile.active和配置檔案的DataID來使不同環境下讀取不同的配置
預設空間+預設分組+新建dev和test兩個DataID
新建dev配置DataID
新建test配置DataID
通過spring.profile.acvice屬性就能進行多環境下配置檔案的讀取
測試
- http://localhost:3377/config/info
- 配置什麼就載入什麼
test
Group方案
通過Group實現環境區分
新建Group
在nacos圖形介面控制檯上新建配置檔案DataID
bootstrap+application
在config下增加一條group的配置即可。可配置為DEV_GROUP或TEST_GROUP
Namespace方案
新建dev/test的Namespace
回到服務管理-服務列表檢視
按照域名配置填寫
YML
Nacos叢集和持久化配置(重要)
官網說明
https://nacos.io/zh-cn/docs
官網架構圖
上圖翻譯
說明
預設Nacos使用嵌入式資料庫實現資料的儲存。所以,如果啟動多個預設置下的Nacos節點,資料儲存是存在一致性問題的。
為了解決這個問題,Nacos採用了集中式儲存的方式來支援叢集化部署,目前只支援MySQL的儲存。
按照上說,我們需要mysql資料庫
官網說明
https://nacos.io/zh-cn/docs/deployment.html
重點說明
Nacos持久化配置解釋
Nacos預設自帶的是嵌入式資料庫derby
derby到mysql切換配置步驟
nacos-server-1.1.4\nacos\conf目錄下找到sql指令碼
nacos-mysql.sql
執行指令碼
這裡說一下具體操作,你自己新建一個nacos_config的資料庫,將對應的sql檔案開啟,複製命令執行即可
nacos-server-1.1.4\nacos\conf目錄下找到application.properties
啟動Nacos,可以看到是個全新的空記錄介面,以前是記錄進derby
Linux版Nacos+MySQL生產環境配置
預計需要,1個nginx+3個nacos註冊中心,1個mysql
Nacos下載Liunx版
- https://github.com/alibaba/nacos/releases
- nacos-server-1.1.4.tar.gz
- 解壓後安裝
叢集配置步驟
1.Linux伺服器上mysql資料庫配置
- SQL指令碼在哪裡
- sql語句原始檔
nacos-mysql.sql - 自己Linux機器上Mysql資料庫貼上
2.application.properties配置
位置
內容
3.Linux伺服器上nacos的叢集配置cluster.conf
梳理出3臺nacos機器的不同服務埠號
複製出cluster.conf
內容
這個IP不能寫127.0.0.1,必須是Linux命令hostname -i能夠識別的IP
4.編輯Nacos的啟動指令碼startup.sh,使他能夠接受不同的啟動埠
/mynacos/nacos/bin 目錄下有startup.sh
在什麼地方,修改什麼,怎麼修改
思考
/mynacos/nacos/bin目錄下有startup.sh
平時單機版的啟動,都是./startup.sh即可。
但是
叢集啟動,我們希望可以類似其它軟體的shell命令,傳遞不同的埠號啟動不同的nacos例項。
命令: ./startup.sh -p 3333表示啟動埠號為3333的nacos伺服器例項,和上一步的cluster.conf配置的一致。
修改內容
執行方式
5.Nginx的配置,由它作為負載均衡器
修改nginx的配置檔案
nginx.conf
按照指定啟動
6.截至到此為止,1個nginx+3個nacos註冊中心+mysql
測試通過nginx訪問nacos
http://192.168.111.144:1111/nacos/#/login
新建一個配置測試
linux伺服器的mysql插入一條記錄
測試
微服務springalibaba-provider-payment9002啟動註冊進nacos叢集
yml
server:
port: 9002
spring:
application:
name: nacos - payment -provider
cloud:
nacos :
discovery:
#配置Nacos地址
#server-addr: localhost:8848
#換成nginx的1111埠,做叢集
server-addr: 192. 168.111.144:1111
management:
endpoints:
web:
exposure:
include: *'