學習地址:https://www.bilibili.com/video/BV18E411x7eT?p=95
源碼分享:https://github.com/mobiwusihuan288/SpringCloud2020
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