1.引言
目前Spring Cloud進入了維護模式,而Spring Cloud alibaba對Spring Cloud做了封裝,使用起來更簡單。包含的功能有服務限流降級、服務注冊於發現、分布式配置管理、消息驅動能力、阿里雲對象存儲、分布式任務調度等。
參考文檔:
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
源代碼:https://github.com/zhongyushi-git/spring-cloud-alibaba-demo.git
2.Nacos
一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平台。是注冊中心與配置中心的組合。官網:https://nacos.io/zh-cn/index.html
2.1下載
打開https://github.com/alibaba/nacos/releases下載需要的版本,這里以1.1.4版本為例說明。

2.2安裝
2.2.1在windows系統安裝
下載壓縮包后解壓即可使用。進入bin目錄,雙擊startup.cmd看到下圖說明運行成功。

默認是以集群方式啟動,若啟動報錯,那么需要修改為單機版啟動,在bin目錄打開cmd,輸入下面的命令進行啟動。
startup.cmd -m standalone
訪問http://localhost:8848/nacos,登錄用戶名和密碼都是nacos。登錄之后的頁面如下,可以看到相關想信息。

2.2.2在Linux系統安裝
把下載好的壓縮上傳制到Linux后解壓
tar -zxvf nacos-server-1.1.4.tar.gz -C /usr/local
解壓之后單機版啟動,啟動之后在瀏覽器訪問nacos首頁,同上。
bash startup.sh -m standalone
2.3基礎環境搭建
創建maven的父工程spring-cloud-alibaba-demo,刪除src目錄。導入依賴,進行版本鎖定
<!--統一管理jar包版本-->
<properties>
<spring.boot.version>2.2.2.RELEASE</spring.boot.version>
<spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
</properties>
<!-- 依賴管理,父工程鎖定版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<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>
2.4服務注冊
1)創建服務提供者子模塊cloud-alibaba-provider8001,導入依賴
<dependencies>
<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>
<!--springcloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2)application.yml配置
server:
port: 8001
spring:
application:
name: cloud-alibaba-nacos-provider
cloud:
#配置nacos地址
nacos:
#服務器地址
server-addr: 127.0.0.1:8848
#服務注冊與發現地址
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
#開啟端口暴露
management:
endpoints:
web:
exposure:
include: "*"
3)創建啟動類
package com.zys.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderMain8001 {
public static void main(String[] args) {
SpringApplication.run(NacosProviderMain8001.class,args);
}
}
4)創建controller接口
package com.zys.cloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Value("${server.port}")
private String port;
@GetMapping("/user/get")
public String get() {
return "provider port is :" + port;
}
}
5)啟動服務提供者,在nacos頁面的服務列表中可以看到服務已注冊進來。那么此時服務的注冊就已完成,非常簡單。

6)同理,按照cloud-alibaba-provider8001方式創建服務提供者子模塊cloud-alibaba-provider8002,端口為8002。啟動后發現nacos中服務的集群數目變成了2。
2.5服務調用
nacos並不提供服務調用的方法,因此還需要使用SpringCloud的方式進行調用,這里使用OpenFeign進行說明(關於OpenFeign的用法其他文章已介紹)。
1)創建服務消費者子模塊cloud-alibaba-consumer80,導入依賴
<dependencies>
<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>
<!--springcloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2)application.yml配置
server:
port: 80
spring:
application:
name: cloud-alibaba-nacos-consumer
cloud:
#配置nacos地址
nacos:
#服務器地址
server-addr: 127.0.0.1:8848
#服務注冊與發現地址
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
feign:
client:
config:
#指定全局
default:
#連接超時時間
connectTimeout: 5000
#服務等待時間
readTimeout: 5000
loggerLevel: full
logging:
level:
com.zys.cloud.client.UserClient: debug
雖然是調用別的服務,但也需要把自身服務注冊到nacos.
3)創建啟動類
package com.zys.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerMain80 {
public static void main(String[] args) {
SpringApplication.run(ConsumerMain80.class, args);
}
}
4)創建Client接口,用於接口映射
package com.zys.cloud.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(value = "cloud-alibaba-nacos-provider")
public interface UserClient {
@GetMapping("/user/get")
String get();
}
5)創建controller接口
package com.zys.cloud.controller;
import com.zys.cloud.client.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
private UserClient userClient;
@GetMapping("/get")
public String get() {
return userClient.get();
}
}
6)啟動服務,可以在nacos頁面的服務列表中看到兩個注冊的服務。

訪問http://localhost/consumer/get,看到是8001和8002進行輪詢負載的。是因為nacos默認支持負載均衡,原因是它默認引入了ribbon。
2.6服務配置
2.6.1基本配置
為了不改動上述的代碼,這里新建一個模塊說明服務的配置,原理是一樣的。
1)創建配置的客戶端子模塊cloud-alibaba-config-client,導入依賴
<dependencies>
<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>
<!--springcloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
這里同時引入了服務注冊和服務配置的依賴。作為客戶端,當然需要注冊到nacos,而配置又是此服務必不可少的。
2)yml配置
bootstrap.yml:系統級別的配置,主要配置配置中心的相關信息。
spring:
cloud:
nacos:
#服務器地址
server-addr: 127.0.0.1:8848
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
config:
#配置中心地址
server-addr: ${spring.cloud.nacos.server-addr}
#指定配置的格式,有yaml和properties兩種
file-extension: yaml
application.yml:主要配置服務的名稱及激活的配置文件
spring:
application:
name: nacos-config-client
profiles:
active: dev
3)創建啟動類
package com.zys.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain.class,args);
}
}
4)創建controller接口
package com.zys.cloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
//動態刷新
@RefreshScope
public class UserController {
@Value("${config.info}")
private String info;
@GetMapping("/config/get")
public String get() {
return "The config info is :" + info;
}
}
需要注意的是,這里在類上加了@RefreshScope注解,用於自動刷新。若不添加,則無法進行自動的配置刷新。
5)創建統一的配置文件
在創建之前,先了解一些dataID的命名規則,它的完整格式為${prefix}-${spring.profile.active}.${file-extension}。
prefix :默認為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。
spring.profile.active :即為當前環境對應的 profile。
file-exetension: 為配置內容的數據格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前只支持 properties 和 yaml 類型。
假如spring.application.name=nacos-config-client,環境為dev,后綴名是yaml,那么dataID就是nacos-config-client-dev.yaml。這里不存在主/從配置文件的說法,只指定不同環境的配置,公共的配置都放在自己的環境中。另外,dataId后綴必須是yaml或properties。
了解之后,就在nacos的配置管理頁面新建一個配置文件,然后發布。

配置代碼:
server:
port: 3344
config:
info: '我的名字叫張三'
6)測試
啟動3344,訪問http://localhost:3344/config/get,可以看到配置的信息。然后修改配置中的config.info內容,再刷新頁面,發現配置信息也更新了。此時就做到了配置實時刷新。
2.6.2分類配置
級別大小:namespace > Group > dataId。
1)dataId方案
一個dateId就是一個配置文件。在nacos頁面再創建一個配置文件,作為測試環境配置

修改application.yml的環境為test。

重啟后訪問http://localhost:3355/config/get,可以看到test環境的配置信息。
2)Group方案
在上述的章節中,並沒有去指定Group,而是采用的默認的名稱DEFAULT_GROUP,如果需要自定義分組名稱,則在創建配置時指定分組名即可,不過需要在bootstrap.yml在指定組名。
新建一個配置文件,分組名為GROUP_TEST

修改application.yml的環境為info,然后在bootstrap.yml指定組名

重啟后訪問http://localhost:3344/config/get,可以看到info環境的配置信息。
3)namespace方案
用於區分不同的部署環境,實現隔離。命名空間是最大的,需要設置的話就創建命名空間(id一般不指定,自動生成即可),在配置文件中指定創建的命名空間的id即可。

2.7持久化配置
nacos默認自帶的是嵌入式數據庫derby,持久化就需要切換到MySQL,MySQL版本5.7以上。
1)執行sql腳本
在下載的nacos文件夾中,nacos-server-1.1.4\nacos\conf\nacos-mysql.sql即是sql腳本,先創建一個名為nacos的數據庫,然后執行這個腳本即可。
2)修改配置文件
打開nacos-server-1.1.4\nacos\conf\application.properties,在最后添加
#增加支持mysql數據源配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
3)啟動測試
重啟nacos,發現之前配置的信息沒有了,原因是MySQL中並沒有進行配置。這時在nacos頁面創建一個名為nacos-config-client-info.yaml的配置文件如下:

啟動服務配置客戶端,訪問http://localhost:3344/config/get,可以看到info環境的配置信息。其配置信息在表config_info中可看到。
2.8集群配置
在搭建集群之前,默認在Linux已安裝完成nocas。另外,nginx單機版也在Linux搭建完成,用於負載均衡nacos服務,MySQL在Linux已安裝完成(MySQL版本5.7+)。
1)執行sql腳本(同上一小節)
2)配置nacos數據源,修改application.properties文件,在最后添加
#增加支持mysql數據源配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
3)獲取本機的ip
hostname -i
4)配置cluster.conf
打開文件
cp cluster.conf.example cluster.conf
vim cluster.conf
把內容修改如下:
172.16.68.248:8849
172.16.68.248:8850
172.16.68.248:8851
需要注意的是,這里的ip必須是上一步獲取的本機ip。
5)修改startup.sh啟動文件
vim startup.sh
修改的文件前后對比,主要添加了啟動的端口號



6)啟動集群
./startup.sh -p 8849
./startup.sh -p 8850
./startup.sh -p 8851
在啟動的時候,遇到了一個大坑,就是安裝的jdk必須手動配置java_home,否則會報錯。
3.Sentinel
學習地址:https://github.com/alibaba/Sentinel/wiki/介紹。
Sentinel主要從流量控制、熔斷降級、系統負載保護維度保護服務的穩定性。
3.1下載與安裝
1)下載地址https://github.com/alibaba/Sentinel/releases,選擇對應的版本下載即可。這里以1.8.2版本為例

可以下載壓縮包,也可以直接下載jar。本章節在Windows中說明,就直接下載jar進行說明。
2)下載到本地后,在其目錄下打開cmd,輸入命令
java -jar sentinel-dashboard-1.7.2.jar
3)在瀏覽器訪問http://localhost:8080,看到下面的頁面說明安裝成功。

用戶名和密碼都是sentinel。
4)登錄后看到儀表盤是空的,因為現在沒有監控任何的服務。
3.2初始化監控
為了不改動上述的代碼,這里新建一個模塊進行說明,原理是一樣的。
1)創建一個模塊cloud-alibaba-sentinel,導入依賴
<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>
<!--springcloud alibaba nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--springcloud alibaba sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2)配置application.yml,簡單起見,配置文件在本地進行配置
server:
port: 8401
spring:
application:
name: cloud-alibaba-sentinel-service
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
sentinel:
transport:
# sentinel dashboard的地址
dashboard: 127.0.0.1:8080
# sentinel dashboard內部通信端口,默認為8719,如果被占用會自動+1,直到找到為止
port: 8719
management:
endpoints:
web:
exposure:
include: "*"
3)創建啟動類
package com.zys.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelMain {
public static void main(String[] args) {
SpringApplication.run(SentinelMain.class, args);
}
}
4)創建controller
package com.zys.cloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FlowLimitController {
@GetMapping("/testA")
public String testA(){
return "--------testA";
}
@GetMapping("/testB")
public String testB(){
return "--------testB";
}
}
5)測試。先啟動nacos服務,再啟動sentinel服務,再啟動8401。訪問http://localhost:8401/testA后會在儀表盤看到生成了一個服務:

將接口testA多調用幾次,再看儀表盤

其中QBS表示1秒的請求數,QPS表示1秒的拒絕請求數。
原理:只要服務加入了Sentienl並進行了配置,那么在調用服務時,就會通過內部通信服務把日志信息發送給dashboard服務,其在頁面上展示。因此只有的服務調用時dashboard才會進行初始化。
6)簇點鏈路
打開簇點鏈路的菜單,可以看到鏈路的信息,可操作的按鈕包含流控、熔斷、熱點和授權,后續一一介紹。

3.2流控
流控:流量控制(flow control),其原理是監控應用流量的QPS或並發線程數等指標,當達到指定的閾值時對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應用的高可用性。
3.2.1閾值類型-QPS
QPS表示每秒的請求數。可在簇點鏈路中選擇鏈路的點擊流控按鈕添加,也可在流控規則中添加。其他的功能類似。這里以/testA的流控為例:

上圖的配置,也就是說對於請求/testA,當每秒請求的次數超過閾值,那么會直接返回失敗的信息。保存后顯示列表如下:

訪問localhost:8401/testA結果是正常的,若快速的刷新幾次,會發現返回了流控的信息:

對於針對來源,默認使用default,那么也可以指定來源,那么當指定的這個來源調用/testA請求時會進行流控,其他服務調用/testA時不進行流控,也就是對來源進行針對性的流控。

3.3.2閾值類型-並發線程數
當然也可設置並發線程的閾值,當某一時刻並發線程數量超過時會進行流控。
1)點擊編輯,將/testA的閾值類型修改並發線程數

2)使用Jmeter對/testA發送超過閾值的並發請求,那么在發送的同時再訪問/testA就會出現流控。
3.3.3 流控模式-關聯
1)說明:前面的兩種的流程模式都設置為直接,這種模式是默認的,也就是說流量控制規則到達閾值時直接觸發流量控制。本小節說明關聯模式,均以QPS類型說明,后同。
2)關聯:當兩個資源之間具有資源爭搶或者依賴關系的時候,這兩個資源便具有了關聯。比如對數據庫同一個字段的讀操作和寫操作存在爭搶,讀的速度過高會影響寫得速度,寫的速度過高會影響讀的速度。如果放任讀寫操作爭搶資源,則爭搶本身帶來的開銷會降低整體的吞吐量。關聯的關系是反向關聯。
3)上述代碼中的/testA和/testB就是關聯關系,它們在同一個controller中,占用相同的資源,編輯配置如下:

使用Jmeter對/testB發送超過閾值的並發請求,那么在發送的同時再訪問/testA就會出現流控。原因是兩個請求相互爭搶資源,進行了流控。
3.3.3 流控模式-鏈路
鏈路模式也就是對某一條鏈路進行流控。如用戶服務會調用訂單服務,商品服務也會調用訂單服務,就存在兩條鏈路。在某個時刻,對商品服務->訂單服務這條鏈路進行流控,從而保證訂單服務的正常使用,最終讓用戶服務可以正常調用訂單服務,雖然限流了商品服務這條鏈路,但不影響用戶服務這條鏈路。
3.3.4流控效果-快速失敗
默認的流量控制方式,當QPS超過任意規則的閾值后,新的請求就會被立即拒絕,拒絕方式為拋出FlowException 。前面已經使用過多次。
3.3.5流控效果-Warm Up
預熱/冷啟動方式。當系統長期處於低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。它有一個冷加載因子,值是3。曲線圖如下:

新加/testA的流控規則如下:

當1秒同時有20個請求,預熱時間是10秒。那么服務會先處理7個請求(20/3),后面依次處理,當達到20秒時處理完所有的請求。
3.3.6流控效果-排隊等待
讓請求以均勻的速度通過。修改/testA的規則:

也就是說,當有大量的請求來時,每秒只處理20個請求,其他的請求進行排隊等待,依次類推。當后面排隊的時間超過5秒時就報錯,顯示流控信息。
3.3熔斷降級
一個服務常常會調用別的模塊,如果依賴的服務出現了不穩定的情況,請求的響應時間變長,那么調用服務的方法的響應時間也會變長,線程會產生堆積,最終可能耗盡業務自身的線程池,服務本身也變得不可用。而Sentinel在服務出現不穩定情況時,會對其進行限制,請求快速失敗,避免影響到其他資源而導致級聯錯誤。當資源被降級后,在接下來的時間窗口內,對該資源的調用都自動熔斷。
3.3.1降級策略
(1)慢調用比例:當單位統計時長內請求數目大於設置的最小請求數目,並且平均響應時間超過最大RT的請求的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。
經過熔斷時長后熔斷器會進入探測恢復狀態,若接下來的一個請求成功完成則結束熔斷,否則會再次被熔斷。

說明:在1000ms內請求數超過5個,且平均響應時間超過300ms的請求的比例(超過300ms的請求占總請求的比例)大於0.4,則該資源自動熔斷10s。10s后根據下一個請求判斷是否再次被熔斷。
(2)異常比例:當單位統計時長內請求數目大於設置的最小請求數目,並且異常的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。
經過熔斷時長后熔斷器會進入探測恢復狀態,若接下來的一個請求成功完成則結束熔斷,否則會再次被熔斷。

說明:在1000ms內請求數超過5個,且異常的比例(異常的請求占總請求的比例)大於0.8,則該資源自動熔斷15s。15s后根據下一個請求判斷是否再次被熔斷。
(3)異常數:當單位統計時長內的異常數目超過閾值之后會自動進行熔斷。
經過熔斷時長后熔斷器會進入探測恢復狀態,若接下來的一個請求成功完成則結束熔斷,否則會再次被熔斷。

說明:在1000ms內請求數超過5個,且異常的請求超過6個,那么該資源將自動熔斷20s。20s后根據下一個請求判斷是否再次被熔斷。
3.3.2注解@SentinelResource的使用
前面的所講的流控或降級,其返回的數據都是 Blocked by Sentinel (flow limiting) ,當然可以自定義。@SentinelResource和@HystrixCommand的作用是類似的,都是來指定流控或降級時返回的信息。
在方法上加@SentinelResource注解,且使用blockHandler(或者blockHandlerClass)指定流控或降級時的自定義提示,而blockHandler函數訪問范圍需要是public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配並且最后加一個額外的參數(類型是BlockException),且和原方法在同一個類中。使用fallback 指定未流控或降級發生異常時的自定義提示,其方法必須是public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配。
下面通過對/testC進行流控和降級來說明:
1)流控配置:

2)降級配置:

3)后台代碼:
@GetMapping("/testC") @SentinelResource(value = "aaa", blockHandler = "testCBlockHandler",fallback = "testCFallback") public String testC(Integer id) { if (id < 0) { throw new RuntimeException("參數值格式錯誤"); } return "--------testC"; } //自定義降級或熔斷時的提示信息 public String testCBlockHandler(Integer id, BlockException exception) { //判斷異常的類型 if (exception instanceof FlowException) { return "你被限流了,請稍后再試"; } else if (exception instanceof DegradeException) { return "你被降級了,請稍后再試"; } return "當前服務不可用"; } //自定義未限流時發生異常的提示信息 public String testCFallback(Integer id){ return "參數不合法"; }
在@SentinelResource指定了value,其值就是要流控或降級的資源名,必須配置。
當訪問/testC?id=8時,快速刷新,會出現流控提示信息。
當問/testC?id=-5時,刷新1此,會出現錯誤提示信息。
當問/testC?id=-5時,刷新5次以上,會出現降級提示信息。
3.4規則持久化
你有沒有發現,每次無論重啟sentinel服務還是要監控的服務,sentinel頁面的配置規則都會消失,這是因為這些規則沒有持久化,對應大量的配置規則,持久化也非常重要,可將其配置到nacos中。
這里直接在cloud-alibaba-sentinel模塊進行說明:
1)導入依賴
<!--springcloud alibaba sentinel-datasource-nacos-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2)在yml配置,已存在配置省略:
spring: cloud: # 流控規則持久化到nacos datasource: dsl: nacos: server-addr: ${spring.cloud.nacos.server-addr} data-id: ${spring.application.name} group-id: DEFAULT_GROUP data-type: json rule-type: flow
3)在nacos中添加配置文件,如下圖:

json內容:
[ { "resource": "/testA", "limitApp": "default", "grade": 1, "count": 5, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
可看到json中是一個數組,數組中只有一個元素,那么針對/test的請求的配置規則會存下來,不會因為重啟而丟失,而其他的請求的配置規則還是丟失。針對這些請求,都按照這種規則配置在數組中即可。
4.Seata
官網:https://seata.io/zh-cn/index.html
一次業務操作需要跨多個數據源或需要跨多個系統進行遠程調用,就會產生分布式事務問題。Seata是一種分布式事務的解決方案,在服務搭建正確的情況下,在業務上添加@GlobalTransactional
4.1術語(一ID+三組件模式)
1)XID:(Transaction ID)全局唯一的事務ID
1)TC:(Transaction Coordinator)事務協調器,維護全局事務的運行狀態,負責協調並驅動全局事務的提交或回滾
2)TM:(Transaction Manager)控制全局事務的邊界,負責開啟一個全局事務,並最終發起全局提交或全局回滾的決議
3)RM:(Resource Manager)控制分支事務,負責分支注冊、狀態匯報,並接收事務協調器的指令,驅動分支(本地)事務的提交和回滾
4.2處理過程
1)TM向TC申請開啟一個全局事務,全局事務創建成功並生成一個全局唯一的XID
2)XID在微服務調用鏈路的上下文中傳播
3)RM向TC注冊分支事務,將其納入XID對應全局事務的管轄
4)TM向TC發起針XID的全局提交或回滾決議
5)TC調度XID下管轄的全部分支事務完成提交或回滾請求。
4.3下載安裝
1)下載地址:https://github.com/seata/seata/releases,下載對應版本即可。
5.微服務架構整合
相比之下,使用SpringCloud+SpringCloud alibaba效果會更好。整合的組件說明如下表:
| 微服務組件 | 框架 | 具體組件 |
| 服務注冊 | SpringCloud alibaba | nacos |
| 服務調用 | SpringCloud | openfeign |
| 服務配置 | SpringCloud alibaba | nacos |
| 服務網關 | SpringCloud | gateway |
| 服務熔斷和降級 | SpringCloud alibaba | sentinel |
| 服務負載均衡 | SpringCloud | Ribbon。默認已有 |
涉及到整合,那么兩者的版本需要進行匹配並進行統一管理。
