版本: 2.2.1
一、簡介
- https://spring.io/projects/spring-cloud-alibaba
- 阿里雲為分布式應用開發提供了一站式解決方案。它包含了開發分布式應用程序所需的所有組件,使您可以輕松地使用springcloud開發應用程序。
- 有了阿里雲,你只需要添加一些注解和少量的配置,就可以將Spring雲應用連接到阿里的分布式解決方案上,用阿里中間件搭建一個分布式應用系統。
二、環境搭建
0.構建項目並引入依賴
<!--定義springcloud版本-->
<properties>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<!--全局引入springcloudalibaba下載依賴地址,並不會引入依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
完整的pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>08-hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>08-hello</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<!--全局引入springcloudalibaba下載依賴地址,並不會引入依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
三、Nacos
0. 簡介
什么是Nacos Name Service & Configurations Services
-
Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。
-
總結:Nacos就是微服務架構中服務注冊中心以及統一配置中心,用來替換原來的(eureka,consul)以及config組件
1. 安裝Nacos
# 0.准備環境
- 1.64 bit OS,支持 Linux/Unix/Mac/Windows,推薦選用 Linux/Unix/Mac。
- 2.64 bit JDK 1.8+;下載 & 配置。
- 3.Maven 3.2.x+;下載 & 配置。
# 1.下載nacos
- https://github.com/alibaba/nacos/releases
# 2.解壓縮安裝包到指定位置
- bin 啟動nacos服務的腳本目錄
- conf nacos的配置文件目錄
- target nacos的啟動依賴存放目錄
- data nacos啟動成功后保存數據的目錄
# 3.啟動安裝服務
- linux/unix/mac啟動
打開終端進入nacos的bin目錄執行如下命令
./startup.sh -m standalone
- windows啟動
在 cmd中
執行 startup.cmd -m standalone 或者雙擊startup.cmd運行文件。
# 4.訪問nacos的web服務管理界面
- http://localhost:8848/nacos/
- 用戶名 和 密碼都是nacos
四、開發服務注冊到nacos
0.創建項目並引入依賴
<!--引入nacos client的依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
完整的pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>09-nacosclient8789</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>09-nacosclient8789</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入nacos client的依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<!--全局引入springcloudalibaba下載依賴地址,並不會引入依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.配置注冊地址
server.port=8789 #指定當前服務端口
spring.application.name=nacosclient #指定服務名稱
spring.cloud.nacos.server-addr=localhost:8848 #指定nacos服務地址
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr} #指定注冊中心地址
management.endpoints.web.exposure.include=* #暴露所有web端點
2.加入啟動服務注冊注解
3.查看nacos的服務列表
五、服務間的通信
RestTemplate+Ribbon
https://www.cnblogs.com/mengd/p/14105955.html
可以看之前寫的文章,基本是一致的
1. 創建項目
首先還是創建兩個項目,users和products
首先products對應的的pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>10-products9098</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>10-products9098</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<!--引入nacos client的依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<!--全局引入springcloudalibaba下載依賴地址,並不會引入依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
以及users對應的pom.xml文件,類似這里就不展示了
2. 配置文件
server.port=9098
spring.application.name=products
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
management.endpoints.web.exposure.include=*
#----------------------------------------------
server.port=9099
spring.application.name=users
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
management.endpoints.web.exposure.include=*
3. nacos中進行查看
啟動nacos,然后再啟動項目
4. constoller
在商品服務中,
package com.md.controller;
/**
* @author md
* @Desc
* @date 2020/12/17 20:38
*/
@RestController
@Slf4j
public class ProductController {
@Value("${server.port}")
private int port;
@GetMapping("/product/find")
public Map<String, Object> find(@RequestParam("id") String id)
{
HashMap<String, Object> map = new HashMap<>();
map.put("status",true);
map.put("msg","當前調用的是商品服務,查詢商品的id:"+id);
map.put("port","當前的端口是:"+port);
return map;
}
}
重啟,進行測試,直接訪問
5. 使用RestTemplate
在users項目中
package com.md.controller;
@RestController
@Slf4j
public class UserController {
@GetMapping("/user/getProductInfo")
public String getProductInfo(String productId){
// 第一種方式. 通過restTemplate直接調用
RestTemplate restTemplate = new RestTemplate();
String forObject = restTemplate.getForObject("http://localhost:9098/product/find?id=" + productId, String.class);
return forObject;
}
}
重啟,再通過users進行訪問
6. restTemplate + ribbon
默認已經有依賴了
直接使用注解的方式
@Configuration
public class RestTemplateConfig {
// 在工廠中創建一個restTemplate對象
@Bean
// 加上這個注解代表當前的restTemplate對象帶有ribbon負載均衡
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
在controller中
package com.md.controller;
@RestController
@Slf4j
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/user/getProductInfo")
public String getProductInfo(String productId){
// 第二種方式,注解的方式
String forObject = restTemplate.getForObject("http://products/product/find?id=" + productId, String.class);
return forObject;
}
}
這樣更加的方便,頁面還是可以正常的方法
7.使用OpenFeign
https://www.cnblogs.com/mengd/p/14111059.html
可以看這個,寫的比較詳細
引入依賴在users中
<!--Open Feign依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
剩下的就不重復寫了
六、使用nacos作為配置中心
1.從nacos獲取配置
創建一個新的項目,還是基於alibaba的環境
# 1.創建項目並引入nacons配置中心依賴
<!--引入nacos client依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入nacos config 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
完整的pom.xml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>11-configclient9066</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>11-configclient9066</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<!--引入nacos client依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入nacos config 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
<!--全局引入springcloudalibaba下載依賴地址,並不會引入依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
# 2.配置配置中心地址
spring.cloud.nacos.server-addr=localhost:8848 # 遠程配置中心的地址
spring.cloud.nacos.config.group=DEFAULT_GROUP # 讀取配置的分組
# 這三者構成了下面的Data ID
spring.cloud.nacos.config.file-extension=properties # 指定讀取文件后綴
spring.application.name=config # 指定讀取文件的前綴
spring.profiles.active=prod # 指定讀取文件的具體環境
注意:寫的時候配置文件不要有注釋
最好還是使用bootstrap.properties
# 3.在nacos中創建配置
這個配置內容就是之前寫的注冊到nacos上的配置,不要寫中文
# 4.編寫控制器測試配置讀取情況
@RestController
@Slf4j
public class HelloController {
//注入配置
@Value("${user.name}")
private String username;
@GetMapping("/hello/config")
public String config(){
log.info("用戶名: [{}]",username);
return username;
}
}
# 5.啟動項目方式測試配置讀取
2. DataId
# 1.DataId
- 用來讀取遠程配置中心的中具體配置文件其完整格式如下:
- ${prefix}-${spring.profile.active}.${file-extension}
a. prefix 默認為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。
b. spring.profile.active 即為當前環境對應的 profile,詳情可以參考 Spring Boot文檔。 注意:當 spring.profile.active 為空時,對應的連接符 - 也將不存在,dataId 的拼接格式變成 ${prefix}.${file-extension}
c. file-exetension 為配置內容的數據格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前只支持 properties 和 yaml 類型。
3.實現自動配置刷新
# 1.自動刷新
- 默認情況下nacos已經實現了自動配置刷新功能,如果需要刷新配置直接在控制器中加入@RefreshScope注解即可
@RestController
@Slf4j
@RefreshScope
public class HelloController {
//注入配置
@Value("${user.name}")
private String username;
@GetMapping("/hello/config")
public String config(){
log.info("用戶名: [{}]",username);
return username;
}
}
4.命名空間
# 1.命名空間(namespace)
- https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
- namespace命名空間是nacos針對於企業級開發設計用來針對於不同環境的區分,比如正在企業開發時有測試環境,生產環境,等其他環境,因此為了保證不同環境配置實現隔離,提出了namespace的概念,默認在nacos中存在一個public命名空間所有配置在沒有指定命名空間時都在這個命名空間中獲取配置,在實際開發時可以針對於不能環境創建不同的namespace空間。默認空間不能刪除!
# 2.創建其他命名空間
- 每個命名空間都有一個唯一id,這個id是讀取配置時指定空間的唯一標識
# 3.在配置列表查看空間
# 4.在指定空間下載創建配置文件
# 5.項目中使用命名空間指定配置
# 6.測試配置
5.配置分組
# 1.配置分組(group)
- 配置分組是對配置集進行分組,通過一個有意義的字符串(如 Buy 或 Trade )來表示,不同的配置分組下可以有相同的配置集(Data ID)。當您在 Nacos 上創建一個配置時,如果未填寫配置分組的名稱,則配置分組的名稱默認采用 DEFAULT_GROUP 。配置分組的常見場景:可用於區分不同的項目或應用,例如:學生管理系統的配置集可以定義一個group為:STUDENT_GROUP。
# 2.創建分組
# 3.讀取不同分組的配置
七、sentinel 流量衛兵
1.什么是sentinel
說明
- https://github.com/alibaba/Sentinel/wiki
- 隨着微服務的普及,服務調用的穩定性變得越來越重要。Sentinel以“流量”為突破口,在流量控制、斷路、負載保護等多個領域進行工作,保障服務可靠性。
- 通俗:用來在微服務系統中保護微服務對的作用 如何 服務雪崩 服務熔斷 服務降級 就是用來替換hystrix
特性
- 豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應用等。
- 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級數據,甚至 500 台以下規模的集群的匯總運行情況。
- 廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。
sentinel使用
- sentinel提供了兩個服務組件:
一個是 sentinel 用來實現微服務系統中服務熔斷、降級等功能。這點和hystrix 類似
一個是 sentinel dashboard 用來監控微服務系統中流量調用等情況。這點和hystrix 類似
2. sentinel dashboard的安裝
# 1.下載
- https://github.com/alibaba/Sentinel/releases
# 2.啟動
- 儀表盤是個jar包可以直接通過java命令啟動 如: java -jar 方式運行 默認端口為 8080
- java -Dserver.port=9191 -jar sentinel-dashboard-1.7.2.jar
默認的端口有沖突,所以啟動的時候指定端口啟動
# 3.訪問web界面
- http://localhost:9191/#/login
# 4.登錄
- 用戶名&密碼: sentinel
3.sentinel 實時監控服務
創建一個新的項目
# 1.創建項目引入依賴
<!--引入nacos client依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入sentinel依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
完整的pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.md</groupId>
<artifactId>09-nacosclient8789</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>09-nacosclient8789</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入nacos client的依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入sentinel依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
<!--全局引入springcloudalibaba下載依賴地址,並不會引入依賴-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
# 2.配置文件
server.port=8789
spring.application.name=nacosclient
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.sentinel.enabled=true # 開啟sentinel 默認開啟
spring.cloud.sentinel.transport.dashboard=localhost:9191 # 連接dashboard
spring.cloud.sentinel.transport.port=8719 # 與dashboard通信的端口
# 3.啟動服務
# 4.訪問dashboard界面查看服務監控
- 發現界面什么都沒有?
- 默認情況下sentiel為延遲加載,不會在啟動之后立即創建服務監控,需要對服務進行調用時才會初始化
# 5.開發服務
@RestController
@Slf4j
public class SentinelController {
@GetMapping("/sentinel/test")
public String test(){
log.info("sentinel test");
return "sentinel test ";
}
@GetMapping("/sentinel/test1")
public String test1(){
log.info("sentinel test1");
return "sentinel test1 ";
}
}
# 6.啟動進行調用
- http://localhost:8789/sentinel/test
# 7.查看監控界面
4.sentinel 流量控制
- 流量控制(flow control),其原理是監控應用流量的 QPS 或並發線程數等指標,當達到指定的閾值時對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應用的高可用性。
- 同一個資源可以創建多條限流規則。FlowSlot 會對該資源的所有限流規則依次遍歷,直到有規則觸發限流或者所有規則遍歷完畢。
- 一條限流規則主要由下面幾個因素組成,我們可以組合這些元素來實現不同的限流效果:
resource:資源名,即限流規則的作用對象
count: 限流閾值
grade: 限流閾值類型(QPS 或並發線程數)
limitApp: 流控針對的調用來源,若為 default 則不區分調用來源
strategy: 調用關系限流策略
controlBehavior: 流量控制效果(直接拒絕、Warm Up、勻速排隊) - 流量控制主要有兩種統計類型,一種是統計並發線程數,另外一種則是統計 QPS
- 更多細節參見官網:https://github.com/alibaba/Sentinel/wiki/流量控制
QPS限流
# 1.配置QPS流量控制
# 2.測試
- 每秒只能最大接收1個請求,超過1個報錯
線程數限流
# 1.配置線程數限流
# 2.訪問測試
流控模式
說明
- 直接:標識流量控制規則到達閾值直接觸發流量控制
- 關聯: 當兩個資源之間具有資源爭搶或者依賴關系的時候,這兩個資源便具有了關聯。比如對數據庫同一個字段的讀操作和寫操作存在爭搶,讀的速度過高會影響寫得速度,寫的速度過高會影響讀的速度。如果放任讀寫操作爭搶資源,則爭搶本身帶來的開銷會降低整體的吞吐量。可使用關聯限流來避免具有關聯關系的資源之間過度的爭搶,舉例來說,read_db 和 write_db 這兩個資源分別代表數據庫讀寫,我們可以給 read_db 設置限流規則來達到寫優先的目的:設置 strategy 為 RuleConstant.STRATEGY_RELATE 同時設置 refResource 為 write_db。這樣當寫庫操作過於頻繁時,讀數據的請求會被限流。
- 鏈路限流: https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
流控效果
- 直接拒絕:(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默認的流量控制方式,當QPS超過任意規則的閾值后,新的請求就會被立即拒絕,拒絕方式為拋出FlowException。
- Warm Up:(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即預熱/冷啟動方式。當系統長期處於低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。
更多:https://github.com/alibaba/Sentinel/wiki/限流---冷啟動 - 勻速排隊:(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式會嚴格控制請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶算法。 只能對請求進行排隊等待
更多:https://github.com/alibaba/Sentinel/wiki/流量控制-勻速排隊模式
4.熔斷降級
- https://github.com/alibaba/Sentinel/wiki/熔斷降級
- 除了流量控制以外,對調用鏈路中不穩定的資源進行熔斷降級也是保障高可用的重要措施之一。由於調用關系的復雜性,如果調用鏈路中的某個資源不穩定,最終會導致請求發生堆積。Sentinel 熔斷降級會在調用鏈路中某個資源出現不穩定狀態時(例如調用超時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而導致級聯錯誤。當資源被降級后,在接下來的降級時間窗口之內,對該資源的調用都自動熔斷(默認行為是拋出
DegradeException
)。
降級策略
- 平均響應時間 (DEGRADE_GRADE_RT):當 1s 內持續進入 N 個請求,對應時刻的平均響應時間(秒級)均超過閾值(count,以 ms 為單位),那么在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的調用都會自動地熔斷(拋出 DegradeException)。注意 Sentinel 默認統計的 RT 上限是 4900 ms,超出此閾值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
- 異常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):當資源的每秒請求量 >= N(可配置),並且每秒異常總數占通過量的比值超過閾值(DegradeRule 中的 count)之后,資源進入降級狀態,即在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的調用都會自動地返回。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。
- 異常數 (DEGRADE_GRADE_EXCEPTION_COUNT):當資源近 1 分鍾的異常數目超過閾值之后會進行熔斷。注意由於統計時間窗口是分鍾級別的,若 timeWindow 小於 60s,則結束熔斷狀態后仍可能再進入熔斷狀態。
5.SentinelResource注解
說明
@GetMapping("/sentinel/test1")
@SentinelResource(value = "aa",blockHandler = "fallBack",fallback = "fall")
public String test1(int id){
log.info("sentinel test1");
if(id<0)
throw new RuntimeException("非法參數!!!");
}
return "sentinel test1 :"+id;
}
//降級異常處理
public String fallBack(int id,BlockException e){
if(e instanceof FlowException){
return "當前服務已被流控! "+e.getClass().getCanonicalName();
}
return "當前服務已被降級處理! "+e.getClass().getCanonicalName();
}
//異常處理
public String fall(int id){
return "當前服務已不可用!";
}
八、.整合環境公共依賴
spring boot 2.2+
springcloud Hoxton
springcloud alibaba 2.2.1+
# 0.構建項目並引入依賴
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!--引入springcloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--引入springcloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>