Nacos服務註冊和配置中心
學習地址:https://www.bilibili.com/video/BV18E411x7eT?p=95
Nacos
官方地址:https://nacos.io/zh-cn/index.html
Nacos:Dynamic Naming and Configuration Service,一個更易於構建雲原生應用的動態服務發現,配置管理和服務管理中心。
Nacos就是註冊中心+配置中心的組合-->Nacos = Eureka+Config+Bus
替代Eureka做服務註冊中心
替代Config做服務配置中心
各種註冊中心比較
服務註冊與發現框架 | CAP模型 | 控制檯管理 | 社群活躍度 |
---|---|---|---|
Eureka | AP | 支援 | 低(2.x版本閉源) |
Zookeeper | CP | 不支援 | 中 |
Consul | CP | 支援 | 高 |
Nacos | AP | 支援 | 高 |
據說Nacos在阿里巴巴內部有超過10萬的例項執行,已經過了類似雙十一等各種大型流量的考驗
安裝執行Nacos
下載地址:https://github.com/alibaba/Nacos
本次演示使用版本:1.3.2
本地Java8+Maven環境已經OK
解壓安裝包,直接執行bin目錄下的startup.cmd
命令執行成功後直接訪問
http://localhost:8848/nacos
預設賬號密碼都是nacos
Nacos作為服務註冊中心
基於Nacos的服務提供者
cloudalibaba-provider-payment9001
-
建module
-
寫POM
<!--父模組--> <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>
<!--9001-->
<?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">
<parent>
<artifactId>springcloud2020</artifactId>
<groupId>com.nuc.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment9001</artifactId>
<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.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>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
</dependencies>
</project>
- 寫YML
server:
port: 9002
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 "nacos registry, serverPort: " + serverPort + "\t id" + id;
}
}
- 測試
Nacos控制檯
http://lcoalhost:9001/payment/nacos/1
cloudalibaba-provider-payment9011
搭建9011
方式一:參照9001搭建
方式二:拷貝虛擬埠對映
測試
基於Nacos的服務消費者
cloudalibaba-consumer-nacos-order83
-
建module
-
寫POM
<?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">
<parent>
<artifactId>springcloud2020</artifactId>
<groupId>com.nuc.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-consumer-nacos-order83</artifactId>
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.nuc.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>
</project>
- 寫YML
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
- 主啟動類
@SpringBootApplication
@EnableDiscoveryClient
public class OrderNacosMain83 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain83.class,args);
}
}
- 業務類
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
@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") Long id) {
return restTemplate.getForObject(serverURL + "/payment/nacos/" + id, String.class);
}
}
- 測試
負載均衡
Nacos包含Ribbon
服務註冊中心對比
Nacos 生態圖
Nacos | Eureka | Consul | CoreDNS | Zookerpper | |
---|---|---|---|---|---|
一致性協議 | CP+AP | AP | CP | / | CP |
健康檢查 | TCP/HTTP/MySQL/Client Beat | Client Beat | TCP/HTTP/gRPC/Cmd | / | Client Beat |
負載均衡 | 權重/DSL/metadata/CMDB | Ribbon | Fabio | RR | / |
雪崩保護 | 支援 | 支援 | 不支援 | 不支援 | 不支援 |
自動登出例項 | 支援 | 支援 | 不支援 | 不支援 | 支援 |
訪問協議 | HTTP/DNS/UDP | HTTP | HTTP/DNS | DNS | TCP |
監聽支援 | 支援 | 支援 | 支援 | 不支援 | 支援 |
多資料中心 | 支援 | 支援 | 支援 | 不支援 | 不支援 |
跨註冊中心 | 支援 | 不支援 | 支援 | 不支援 | 不支援 |
SpringCloud整合 | 支援 | 支援 | 支援 | 不支援 | 不支援 |
Dubbo整合 | 支援 | 不支援 | 不支援 | 不支援 | 支援 |
K8s整合 | 支援 | 不支援 | 支援 | 支援 | 不支援 |
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作為服務配置中心
cloudalibaba-config-nacos-client3377
-
建module
-
寫POM
<?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">
<parent>
<artifactId>springcloud2020</artifactId>
<groupId>com.nuc.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-config-nacos-client3377</artifactId>
<dependencies>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web + actuator-->
<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>
</project>
- 寫YML
# application.yml
spring:
profiles:
active: dev # 表示開發環境
# bootstrap.yml
server:
port: 3377
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服務註冊中心地址
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yaml #指定yaml格式的配置
- 主啟動類
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class,args);
}
}
- 業務類
@RestController
@RefreshScope//動態重新整理
public class ConfigClientController
{
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
- 在Nacos中新增配置資訊
配置規則:https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
${prefix}-${spring.profiles.active}.${file-extension}
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
prefix預設為spring.application.name的值
spring.profile.active既為當前環境對應的profile,可以通過配置項spring.profile.active 來配置
file-exetension為配置內容的資料格式,可以通過配置項
spring.cloud.nacos.config.file-extension配置
- 測試
自帶動態重新整理
修改配置檔案
分類配置
問題1:
實際開發中,通常一個系統會準備
dev開發環境;
test測試環境;
prod生產環境。
如何保證指定環境啟動時服務能正確讀取到Nacos,上相應環境的配置檔案呢?
問題2:
一個大型分散式微服務系統會有很多微服務子專案,
每個微服務專案又都會有相應的開發環境、測試環境、預發環境、正式環境...
那怎麼對這些微服務配置進行管理呢?
Namespace+Group+Data ID三者關係
類似Java裡面的package名和類名
最外層的namespace是可以用於區分部署環境的,Group和DatalD邏輯上區分兩個目標物件。
預設情況:
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實現環境區分
在config下增加一條group的配置即可。可配置為DEV_GROUP或TEST_GROUP
測試
Namespace方案
新建dev/test的Namespace
測試
Nacos叢集和持久化配置
官方說明:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
Nacos支援三種部署模式
- 單機模式 - 用於測試和單機試用。
- 叢集模式 - 用於生產環境,確保高可用。
- 多叢集模式 - 用於多資料中心場景。
架構圖
預設Nacos使用嵌入式資料庫實現資料的儲存。所以,如果啟動多個預設配置下的Nacos節點,資料儲存是存在-致性問題的。為了解決這個問題,Nacos採用 了集中式儲存的方式來支援叢集化部署,目前只支援MySQL的儲存。
MySQL持久化
Nacos預設自帶的是嵌入式資料庫derby
在0.7版本之前,在單機模式時nacos使用嵌入式資料庫實現資料的儲存,不方便觀察資料儲存的基本情況。0.7版本增加了支援mysql資料來源能力,具體的操作步驟:
- 1.安裝資料庫,版本要求:5.6.5+
- 2.初始化mysql資料庫,資料庫初始化檔案:nacos-mysql.sql
- 3.修改conf/application.properties檔案,增加支援mysql資料來源配置(目前只支援mysql),新增mysql資料來源的url、使用者名稱和密碼。
建立資料庫
nacos\conf目錄下找到application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=youdontknow
啟動nacos,可以看到是個全新的空記錄介面,以前是記錄進derby
Linux版Nacos+MySQL生產環境配置
Nacos:1.3.2
MySQL:5.7
Nginx:1.18
Nacos下載linux版本
下載地址:https://github.com/alibaba/Nacos
解壓
移動
叢集配置步驟(重點)
Linux伺服器上mysql資料庫配置
SQL檔案
Mysql執行指令碼,建立資料庫
application.properties配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.110.128:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=P@ssw0rd
叢集配置cluster.conf
這個IP不能寫127.0.0.1,必須是Linux命令hostname -I能夠識別的IP
# 大寫i
hostname -I
編輯啟動指令碼startup.sh
接受不同的啟動端
/mynacos/nacos/bin目錄下有startup.sh
平時單機版的啟動,都是./startup.sh
即可。
叢集啟動,我們希望可以類似其它軟體的shell命令,傳遞不同的埠號啟動不同的nacos例項。
命令: ./startup.sh -p 3333
表示啟動埠號為3333的nacos伺服器例項,和上一步的cluster.conf配置的一 致。
修改埠對映
修改記憶體配置
nohup $JAVA -Dserver.port=${EMBEDDED_STORAGE} ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
JAVA_OPT="${JAVA_OPT} -server -Xms500m -Xmx500m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
啟動測試
Nginx的配置,由它作為負載均衡器
upstream cluster{
server 127.0.0.1:3333;
server 127.0.0.1:4444;
server 127.0.0.1:5555;
}
server {
listen 1111;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://cluster;
}
...
啟動
測試
新建配置
檢視資料庫
9011啟動註冊進nacos叢集
修改YML