SpringCloud Alibaba第十二章,升級篇,服務註冊與配置中心Nacos
一、爲什麼SpringCloud Alibaba
1、爲什麼
有了spring cloud這個微服務的框架,爲什麼又要使用spring cloud alibaba這個框架了?最重要的原因在於spring
cloud中的幾乎所有的組件都使用Netflix公司的產品,然後在其基礎上做了一層封裝,同時也新增了一些其他框架。然而
Netflix的服務發現組件Eureka已經停止更新,同時Feign、Hystrix、Zuul等也都出於升級或停更進入維護階段。
所以急需其他的一些替代產品,也就是spring cloud alibaba。
2、SpringCloud Alibaba能做什麼
1、Nacos
阿里巴巴開源產品,一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。
2、Sentinel
阿里巴巴開源產品,把流量作爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
3、RocketMQ
Apache RocketMQ™ 基於 Java 的高性能、高吞吐量的分佈式消息和流計算平臺。
4、Dubbo
Apache Dubbo™ 是一款高性能 Java RPC 框架。
5、Seata
阿里巴巴開源產品,一個易於使用的高性能微服務分佈式事務解決方案。
6、Alibaba Cloud OSS
阿里雲對象存儲服務(Object Storage Service,簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲
服務。您可以在任何應用、任何時間、任何地點存儲和訪問任意類型的數據。
7、Alibaba Cloud SchedulerX
阿里中間件團隊開發的一款分佈式任務調度產品,支持週期性的任務與固定時間點觸發任務。
8、Alibaba Cloud SMS
覆蓋全球的短信服務,友好、高效、智能的互聯化通訊能力,幫助企業迅速搭建客戶觸達通道。
3、官網和資料
https://github.com/alibaba/spring-cloud-alibaba
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
4、引用
cloud_2020項目總POM中引用:
<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>
</dependencies>
</dependencyManagement>
二、服務註冊與配置中心Nacos
Nacos:Dynamic Naming + Configuration Service
Nacos就是註冊中心+配置中心的組合 == 等價於Eureka+Config+Bus
官網:
https://nacos.io/zh-cn/
https://nacos.io/zh-cn/docs/quick-start.html
1、Nacos下載與安裝(Server)
這裏的nacos即 註冊中心Server
下載地址:
https://github.com/alibaba/nacos/releases/tag/1.2.1
運行:
解壓後bin目錄下的start
瀏覽:
http://localhost:8848/nacos/#/login
賬號:nacos 密碼:nacos
2、服務註冊中心案例(client)
2.1、服務提供者provider-payment-9001
這裏nacos,即註冊中心client
新建module,cloudalibaba-provider-payment-9001
<parent>
<artifactId>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment-9001</artifactId>
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>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment-9001</artifactId>
<dependencies>
<!--nacos discovery服務發現-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.lee.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- web組件 -->
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 9001
spring:
application:
name: nacos-payment-provider #服務名稱
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos server地址
management:
endpoints:
web:
exposure:
include: '*'
主啓動類
@SpringBootApplication
@EnableDiscoveryClient //服務發現
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class,args);
}
}
業務類PaymentController(讀取配置信息)
@RestController
@RequestMapping("/payment")
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id)
{
return "nacos registry, serverPort: "+ serverPort+"\t id"+id;
}
}
測試:
1、啓動nacos server 和 cloudalibaba-provider-payment-9001
2、訪問:
http://localhost:9001/payment/nacos/1
結果:
nacos registry, serverPort: 9001 id1
3、訪問:
http://localhost:8848/nacos
2.2、服務提供者provider-payment-9002
爲了後面測試方便,仿照cloudalibaba-provider-payment-9001創建9002
<parent>
<artifactId>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment-9002</artifactId>
application.yml
server:
port: 9002
spring:
application:
name: nacos-payment-provider #服務名稱
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos server地址
management:
endpoints:
web:
exposure:
include: '*'
2.3、服務消費者consumer-order-83
新建module,cloudalibaba-consumer-order-83
<parent>
<artifactId>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-consumer-order-83</artifactId>
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>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-consumer-order-83</artifactId>
<dependencies>
<!-- nacos服務發現 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.lee.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- web組件 -->
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 83
spring:
application:
name: nacos-order-consumer #服務名稱
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos server地址
主啓動類
@SpringBootApplication
@EnableDiscoveryClient//服務發現
public class OrderMain83 {
public static void main(String[] args) {
SpringApplication.run(OrderMain83.class,args);
}
}
配置類
/**
* 配置類
*/
@Configuration
public class ApplicationContextConfig {
//標註此註解後,RestTemplate就具有了客戶端負載均衡能力---因爲使用了註冊中心
//必須添加此註解,否則java.net.UnknownHostException: NACOS-PAYMENT-PROVIDER
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
業務類
@RestController
@RequestMapping("/consumer")
public class OrderController {
public static final String serverURL = "http://nacos-payment-provider";
@Resource
private RestTemplate restTemplate;
@GetMapping(value = "/payment/nacos/{id}")
public String paymentInfo(@PathVariable("id") Long id)
{
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
}
測試:
1、啓動nacos-server、cloud-provider-payment-9001、cloud-provider-payment-9002、
cloud-consumer-order-83
2、訪問:http://localhost:83/consumer/payment/nacos/1
結果:
nacos registry, serverPort: 9001 id1
和G
nacos registry, serverPort: 9002 id1
輪詢訪問
3、訪問 http://localhost:8848/nacos
結論:nacos內部整合了Ribbon
2.4、各註冊中心比較
2.5、Nacos的AP和CP模式切換
CAP:C數據一致性、A可用寫、P分區容錯性
Nacos默認是AP模式,如下進行切換:
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
何時選擇何種模式:
AP模式:
如果不需要存儲服務級別的信息,且服務實例是通過nacos-client註冊,並能夠保持心跳上報,那麼選擇AP模式。
當前的主流服務如springcloud和dubbo都適用AP模式,AP模式爲了服務的可用性而減弱了一致性,因此AP模式下只支持
註冊臨時實例。
CP模式:
如果需要在服務級別編輯或者存儲配置信息,那麼CP是必須的,K8S服務和DNS服務則適用CP模式。
CP模式支持註冊持久化實例,此時則是以raft協議爲集羣運行模式,該模式下注冊實例之前必須先註冊服務,如果服務不存在,則返回錯誤。
3、服務配置中心案例(client)
3.1、基礎案例
創建cloudalibaba-provider-payment-9003
<parent>
<artifactId>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment-9003</artifactId>
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>cloud_2020</artifactId>
<groupId>com.lee.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloudalibaba-provider-payment-9003</artifactId>
<dependencies>
<!-- nacos配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- nacos服務發現 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.lee.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- web組件 -->
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 9003
spring:
profiles:
active: dev
bootstrap.yml
spring:
application:
name: nacos-payment-provider #服務名稱
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服務註冊中心地址
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yaml #指定yaml格式的配置
主啓動類
@SpringBootApplication
@EnableDiscoveryClient//服務發現
public class PaymentMain9003 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9003.class,args);
}
}
業務類
@RestController
@RefreshScope //實現配置的自動更新
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
3.2、Nacos添加對應配置信息
3.2.1、data id配置規則
${prefix}-${spring.profile.active}.${file-extentsion}
prefix:
默認值爲:spring.application.name,也可以通過spring.cloud.nacos.config.prefix來配置
spring.profile.active:
spring.profile.active不存在時,對應的連接符也將不存在。
對應的data id拼接格式爲:
${prefix}.${file-extension}
file-extension:
爲配置內容的數據格式,可以通過spring.cloud.nacos.config.file-extension來配置。
目前只支持properties和yaml類型
3.2.2、實操
根據cloudalibaba-provider-payment-9003的bootstrap.yml和application.yml兩個配置文件的配置內容,配置如下:
nacos-payment-provider-dev.yaml
配置內容:
config:
info: "config info from nacos config center, nacos-payment-provider-dev.yaml,version:1"
3.3、測試
1、啓動nacos-server、cloudalibaba-provider-payment-9003
2、瀏覽:http://localhost:9003/config/info
結果:
config info from nacos config center, nacos-payment-provider-dev.yaml,version:1
3、在nacos-server中修改配置文件version爲2
4、瀏覽http://localhost:9003/config/info
結果:
config info from nacos config center, nacos-payment-provider-dev.yaml,version:2
結論:
nacos自帶動態刷新功能
3.4、分類配置
一個大型分佈式微服務系統會有很多微服務子項目,每個微服務項目又會產生多個運行環境:開發環境、測試環境、正式環境等。
那麼怎麼對這些微服務配置進行管理呢?
nacos通過namespace+groupID+dataId三者對不同開發環境、不同微服務進行管理
namespace:劃分部署環境DEV\TEST\PROD等,默認PUBLIC
group:劃分微服務項目,如 order user cms等,默認DEFAULT_GROUP
dataID如上面的命名規則
相關配置:
spring:
application:
name: nacos-payment-provider #服務名稱
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服務註冊中心地址
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yaml #指定yaml格式的配置
namespace: 0a294291-a318-4a65-b899-17b08772bb39 #nacos對應的namespaceID
group: CMS #nacos對應的group
namespace配置:
group配置:
測試:
1、啓動nacos-server和cloudalibaba-provider-payment-9003
2、訪問:http://localhost:9003/config/info
結果:
namespace:DEV, Group:CMS, Data ID:nacos-payment-provider-dev.yaml. version:1
結論:
9003通過namespace + group + data ID三者定位配置文件的位置,從而讀取配置文件
4、Nacos集羣及持久化配置
這裏我們只用1個Nginx服務器,3個Nacos, 1個Mysql, 3個Linux
4.1、Nacos集羣安裝及持久化切換
1、準備3臺Linux虛擬機,它們的IP分別是192.168.0.111 - 192.168.0.107 - 192.168.0.112
2、3臺服務器上各自下載nacos
wget https://nacos的下載路徑(在nacos.io官網上找)
3、在nacos的conf目錄根據cluster.conf.example夫指出cluster.conf文件
cp cluster.conf.example cluster.conf
4、編輯cluster.conf文件內容
vi cluster.conf
############文件內容如下--將3臺nacos的服務器地址copy上去即可--將原有內容都刪除##########
192.168.0.111:8848
192.168.0.107:8848
192.168.0.112:8848
5、持久化nacos,修改conf目錄下application.properties文件,將nacos的持久化數據庫從內嵌的Derby切換成本地的MySQL數據庫
vi application.properties
#######在文件底部添加如下--192.168.0.102是我本地windows的IP地址,即MySQL在我windows本地#######
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.0.102:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=admin123
6、關閉linux防火牆
systemctl stop firewalld
##查看防火牆狀態
systemctl status firewalld
4.2、Mysql數據初始化
【我的mysql在windows本地上192.168.0.102,爲了能讓nacos和本地mysql連接,關閉本地的防火牆,開啓mysql遠程訪問權限】
從nacos解壓包的conf目錄下找到nacos-mysql.sql文件
CREATE DATABASE IF NOT EXISTS nacos_config DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
use nacos_config;
將nacos-mysql.sql的文件內容運行一下OK
##本地mysql設置可以遠程訪問
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'admin123' WITH GRANT OPTION;
select user,host from user;
##關閉本地防火牆
4.3、Nginx配置
我的nginx服務安裝在了192.168.0.107上,使用upstream。
nginx需要集成nginx_upstream_check_module模塊,具體安裝方法請看:
https://blog.csdn.net/weixin_30379625/article/details/87693818
4.4、修改cloudalibaba-provider-payment-9003
修改bootstrap.yml,將原來連接nacos的地址修改爲NGINX的服務地址
spring:
application:
name: nacos-payment-provider #服務名稱
cloud:
nacos:
discovery:
#server-addr: localhost:8848 #服務註冊中心地址
server-addr: 192.168.0.107:80 #NGINX的服務地址
config:
#server-addr: localhost:8848 #配置中心地址
server-addr: 192.168.0.107:80 #NGINX的服務地址
file-extension: yaml #指定yaml格式的配置
#namespace: 0a294291-a318-4a65-b899-17b08772bb39 #nacos對應的namespaceID #暫時關閉
#group: CMS #nacos對應的group #暫時關閉
4.5、測試
1、啓動3個nacos服務
cd /opt/software/nacos/bin
sh startup.sh
檢測
可以通過查看日誌:/opt/software/nacos/logs/start.out
也可以通過訪問:
http://192.168.0.111:8848/nacos
http://192.168.0.107:8848/nacos
http://192.168.0.112:8848/nacos
(注意關閉防火牆)
2、啓動NGINX服務
/usr/local/nginx-1.14.1/sbin/nginc -c /usr/local/nginx-1.14.1/conf/nginx.conf
檢測
可以通過訪問:
http://192.168.0.107:80/nacos
(注意關閉防火牆)
通過nginx進入nacos,創建配置文件nacos-payment-provider-dev.yaml
配置格式yaml,配置內容如下:
config:
info: "this is nacos cluster,version:1"
3、啓動cloudalibaba-provider-payment-9003
訪問:http://localhost:9003/config/info
結果:
this is nacos cluster,version:1
測試成功,nacos集羣配置成功!
(在nacos集羣管理可以看到各nacos的服務詳情)