Sentinel原理與SpringBoot整合實(shí)戰(zhàn)案例講解
前言
隨著微服務(wù)架構(gòu)的廣泛應(yīng)用,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要。在高并發(fā)場(chǎng)景下,如何保障服務(wù)的穩(wěn)定性和可用性成為了一個(gè)關(guān)鍵問題。阿里巴巴開源的Sentinel作為一個(gè)面向分布式服務(wù)架構(gòu)的流量控制組件,提供了從流量控制、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來保障服務(wù)穩(wěn)定性的解決方案。
本文將詳細(xì)介紹Sentinel的核心原理和基本功能點(diǎn),并提供一個(gè)完整的SpringBoot整合Sentinel的案例,幫助讀者快速掌握Sentinel的使用方法。
一、Sentinel簡(jiǎn)介
1.1 什么是Sentinel
Sentinel是阿里巴巴開源的,面向分布式服務(wù)架構(gòu)的流量控制組件,主要以流量為切入點(diǎn),從流量控制、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來保障服務(wù)的穩(wěn)定性。
Sentinel的主要特性包括:
- 豐富的應(yīng)用場(chǎng)景:Sentinel承接了阿里巴巴近10年的雙十一大促流量的核心場(chǎng)景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)、消息削峰填谷、集群流量控制、實(shí)時(shí)熔斷下游不可用應(yīng)用等。
- 完備的實(shí)時(shí)監(jiān)控:Sentinel同時(shí)提供實(shí)時(shí)的監(jiān)控功能。用戶可以在控制臺(tái)中看到接入應(yīng)用的單臺(tái)機(jī)器秒級(jí)數(shù)據(jù),甚至500臺(tái)以下規(guī)模的集群的匯總運(yùn)行情況。
- 廣泛的開源生態(tài):Sentinel提供開箱即用的與其它開源框架/庫的整合模塊,例如與Spring Cloud、Apache Dubbo、gRPC、Quarkus的整合。用戶只需要引入相應(yīng)的依賴并進(jìn)行簡(jiǎn)單的配置即可快速地接入Sentinel。同時(shí)Sentinel提供Java/Go/C++等多語言的原生實(shí)現(xiàn)。
- 完善的SPI擴(kuò)展機(jī)制:Sentinel提供簡(jiǎn)單易用、完善的SPI擴(kuò)展接口。用戶可以通過實(shí)現(xiàn)擴(kuò)展接口來快速地定制邏輯。例如定制規(guī)則管理、適配動(dòng)態(tài)數(shù)據(jù)源等。
1.2 Sentinel與其他熔斷降級(jí)工具的對(duì)比
相比于其他熔斷降級(jí)工具(如Hystrix),Sentinel具有以下優(yōu)勢(shì):
- 豐富的流量控制:Sentinel提供了更豐富的流量控制策略,包括基于調(diào)用關(guān)系的流量控制、熱點(diǎn)參數(shù)限流等。
- 實(shí)時(shí)監(jiān)控:Sentinel提供了實(shí)時(shí)的監(jiān)控功能,可以實(shí)時(shí)查看接入應(yīng)用的運(yùn)行情況。
- 輕量級(jí)設(shè)計(jì):Sentinel采用輕量級(jí)設(shè)計(jì),不依賴任何框架/庫,能夠運(yùn)行于所有Java運(yùn)行時(shí)環(huán)境。
- 多語言支持:Sentinel提供了Java/Go/C++等多語言的原生實(shí)現(xiàn)。
- 完善的SPI擴(kuò)展機(jī)制:Sentinel提供了完善的SPI擴(kuò)展接口,用戶可以通過實(shí)現(xiàn)擴(kuò)展接口來快速地定制邏輯。
二、Sentinel核心原理
2.1 基本工作原理
Sentinel的核心工作原理可以概括為:
- 資源定義:資源是Sentinel的核心概念,它可以是Java應(yīng)用程序中的任何內(nèi)容,例如,由應(yīng)用程序提供的服務(wù),或由應(yīng)用程序調(diào)用的其它應(yīng)用提供的服務(wù),甚至可以是一段代碼。只要通過Sentinel API定義的代碼,就是資源。
- 規(guī)則配置:Sentinel通過規(guī)則來指定資源的訪問控制策略。規(guī)則包括流量控制規(guī)則、熔斷降級(jí)規(guī)則、系統(tǒng)保護(hù)規(guī)則、來源訪問控制規(guī)則和熱點(diǎn)參數(shù)規(guī)則等。
- 統(tǒng)計(jì)與判斷:Sentinel會(huì)實(shí)時(shí)統(tǒng)計(jì)資源的調(diào)用數(shù)據(jù),并根據(jù)預(yù)設(shè)的規(guī)則進(jìn)行判斷,若超出閾值,則采取相應(yīng)的流量控制措施。
2.2 Sentinel的執(zhí)行流程
Sentinel的執(zhí)行流程主要分為以下幾個(gè)步驟:
- 資源埋點(diǎn):通過
SphU.entry(resourceName)和entry.exit()方法對(duì)資源進(jìn)行埋點(diǎn)。 - 規(guī)則判斷:當(dāng)資源被訪問時(shí),Sentinel會(huì)根據(jù)預(yù)設(shè)的規(guī)則進(jìn)行判斷。
- 流量控制:如果觸發(fā)了規(guī)則條件,Sentinel會(huì)執(zhí)行相應(yīng)的流量控制措施,例如直接拒絕、排隊(duì)等待或預(yù)熱模式。
- 熔斷降級(jí):對(duì)于響應(yīng)時(shí)間過長或異常比例過高的服務(wù),Sentinel會(huì)進(jìn)行熔斷降級(jí)處理。
- 系統(tǒng)自適應(yīng)保護(hù):當(dāng)系統(tǒng)負(fù)載過高時(shí),Sentinel會(huì)自動(dòng)進(jìn)行系統(tǒng)保護(hù)。
2.3 Sentinel的核心組件
Sentinel的核心組件主要包括:
- Sentinel核心庫:不依賴任何框架/庫,能夠運(yùn)行于所有Java運(yùn)行時(shí)環(huán)境,同時(shí)對(duì)Dubbo/Spring Cloud等框架也有較好的支持。
- Sentinel控制臺(tái):基于Spring Boot開發(fā),打包后可以直接運(yùn)行,不需要額外的Tomcat等應(yīng)用容器。
三、Sentinel基本功能點(diǎn)
3.1 流量控制
流量控制(flow control)是Sentinel最核心的功能之一,其原理是監(jiān)控應(yīng)用流量的QPS或并發(fā)線程數(shù)等指標(biāo),當(dāng)達(dá)到指定的閾值時(shí)對(duì)流量進(jìn)行控制,以避免被瞬時(shí)的流量高峰沖垮,從而保障應(yīng)用的高可用性。
流量控制主要有以下幾個(gè)維度:
基于QPS/并發(fā)數(shù)的流量控制:
- 并發(fā)數(shù)控制:用于保護(hù)業(yè)務(wù)線程池不被慢調(diào)用耗盡。
- QPS控制:當(dāng)QPS超過某個(gè)閾值的時(shí)候,采取措施進(jìn)行流量控制。
流量控制效果:
- 直接拒絕:默認(rèn)的流量控制方式,當(dāng)QPS超過任意規(guī)則的閾值后,新的請(qǐng)求就會(huì)被立即拒絕。
- Warm Up:預(yù)熱/冷啟動(dòng)方式,讓通過的流量緩慢增加,在一定時(shí)間內(nèi)逐漸增加到閾值上限。
- 勻速排隊(duì):嚴(yán)格控制請(qǐng)求通過的間隔時(shí)間,讓請(qǐng)求以均勻的速度通過,對(duì)應(yīng)的是漏桶算法。
基于調(diào)用關(guān)系的流量控制:
- 根據(jù)調(diào)用方來源進(jìn)行流量控制。
- 支持針對(duì)不同的調(diào)用方設(shè)置不同的流控策略。
3.2 熔斷降級(jí)
熔斷降級(jí)(circuit breaking)是Sentinel的另一個(gè)重要功能,它用于當(dāng)調(diào)用鏈路中某個(gè)資源出現(xiàn)不穩(wěn)定狀態(tài)時(shí)(例如調(diào)用超時(shí)或異常比例升高),對(duì)這個(gè)資源的調(diào)用進(jìn)行限制,讓請(qǐng)求快速失敗,避免影響到其它的資源而導(dǎo)致級(jí)聯(lián)錯(cuò)誤。
熔斷降級(jí)主要有以下幾個(gè)維度:
- 慢調(diào)用比例:當(dāng)資源的響應(yīng)時(shí)間超過閾值(慢調(diào)用)的比例超過設(shè)定的比例閾值時(shí),觸發(fā)熔斷。
- 異常比例/異常數(shù):當(dāng)資源的異常比例或異常數(shù)超過閾值時(shí),觸發(fā)熔斷。
- 恢復(fù)策略:熔斷觸發(fā)后,經(jīng)過一段時(shí)間(即熔斷超時(shí)時(shí)間),熔斷器會(huì)進(jìn)入探測(cè)恢復(fù)狀態(tài),若接下來的一個(gè)請(qǐng)求處理成功,則結(jié)束熔斷,否則繼續(xù)熔斷。
3.3 熱點(diǎn)參數(shù)限流
熱點(diǎn)參數(shù)限流是一種更細(xì)粒度的流量控制,它允許用戶針對(duì)某個(gè)熱點(diǎn)參數(shù)進(jìn)行限流,例如針對(duì)某個(gè)用戶ID限流。
熱點(diǎn)參數(shù)限流的特點(diǎn):
- 可以針對(duì)某個(gè)參數(shù)的特定值單獨(dú)設(shè)置限流閾值。
- 支持多種參數(shù)類型,包括基本類型和字符串類型。
- 可以設(shè)置參數(shù)例外項(xiàng),對(duì)特定的參數(shù)值進(jìn)行不同的限流處理。
3.4 系統(tǒng)自適應(yīng)限流
系統(tǒng)自適應(yīng)限流從整體維度對(duì)應(yīng)用入口流量進(jìn)行控制,結(jié)合應(yīng)用的Load、CPU使用率、總體平均RT、入口QPS和并發(fā)線程數(shù)等幾個(gè)維度的監(jiān)控指標(biāo),通過自適應(yīng)的流控策略,讓系統(tǒng)的入口流量和系統(tǒng)的負(fù)載達(dá)到一個(gè)平衡,讓系統(tǒng)盡可能跑在最大吞吐量的同時(shí)保證系統(tǒng)整體的穩(wěn)定性。
系統(tǒng)規(guī)則包含以下幾個(gè)重要的參數(shù):
- Load:當(dāng)系統(tǒng)load1超過閾值,且系統(tǒng)當(dāng)前的并發(fā)線程數(shù)超過系統(tǒng)容量時(shí)才會(huì)觸發(fā)系統(tǒng)保護(hù)。
- CPU使用率:當(dāng)系統(tǒng)CPU使用率超過閾值即觸發(fā)系統(tǒng)保護(hù)。
- 平均RT:當(dāng)單臺(tái)機(jī)器上所有入口流量的平均RT達(dá)到閾值即觸發(fā)系統(tǒng)保護(hù)。
- 并發(fā)線程數(shù):當(dāng)單臺(tái)機(jī)器上所有入口流量的并發(fā)線程數(shù)達(dá)到閾值即觸發(fā)系統(tǒng)保護(hù)。
- 入口QPS:當(dāng)單臺(tái)機(jī)器上所有入口流量的QPS達(dá)到閾值即觸發(fā)系統(tǒng)保護(hù)。
3.5 黑白名單控制
黑白名單控制根據(jù)資源的請(qǐng)求來源(origin)限制資源是否通過:
- 白名單:來源(origin)在白名單內(nèi)的請(qǐng)求才可通過。
- 黑名單:來源(origin)在黑名單內(nèi)的請(qǐng)求不允許通過。
3.6 實(shí)時(shí)監(jiān)控
Sentinel提供實(shí)時(shí)的監(jiān)控功能,用戶可以實(shí)時(shí)查看接入應(yīng)用的單臺(tái)機(jī)器秒級(jí)數(shù)據(jù),甚至500臺(tái)以下規(guī)模的集群的匯總運(yùn)行情況。監(jiān)控?cái)?shù)據(jù)包括:
- 通過的請(qǐng)求數(shù)(pass):一秒內(nèi)到來到的請(qǐng)求。
- 被阻止的請(qǐng)求數(shù)(blocked):一秒內(nèi)被流量控制的請(qǐng)求數(shù)量。
- 成功處理的請(qǐng)求數(shù)(success):一秒內(nèi)成功處理完的請(qǐng)求。
- 總請(qǐng)求數(shù)(total):一秒內(nèi)到來的請(qǐng)求以及被阻止的請(qǐng)求總和。
- 平均響應(yīng)時(shí)間(RT):一秒內(nèi)該資源的平均響應(yīng)時(shí)間。
- 異常數(shù)(exception):一秒內(nèi)業(yè)務(wù)本身異常的總和。
3.7 動(dòng)態(tài)規(guī)則配置
Sentinel支持多種動(dòng)態(tài)規(guī)則源,包括:
- 文件配置:規(guī)則存儲(chǔ)在文件中,定期輪詢文件獲取規(guī)則。
- Nacos配置中心:規(guī)則存儲(chǔ)在Nacos配置中心,通過監(jiān)聽配置變更事件即時(shí)獲取規(guī)則。
- ZooKeeper:規(guī)則存儲(chǔ)在ZooKeeper中,通過監(jiān)聽節(jié)點(diǎn)變更事件即時(shí)獲取規(guī)則。
- Apollo配置中心:規(guī)則存儲(chǔ)在Apollo配置中心,通過監(jiān)聽配置變更事件即時(shí)獲取規(guī)則。
- Redis:規(guī)則存儲(chǔ)在Redis中,通過定期輪詢獲取規(guī)則。
四、SpringBoot整合Sentinel完整案例
下面我們將通過一個(gè)完整的案例,演示如何在SpringBoot項(xiàng)目中整合Sentinel。
4.1 項(xiàng)目結(jié)構(gòu)
springcloud-sentinel ├── src │ └── main │ ├── java │ │ └── com.example │ │ ├── config │ │ │ └── SentinelConfig.java │ │ ├── controller │ │ │ └── TestSentinelController.java │ │ ├── service │ │ │ └── HelloService.java │ │ └── SentinelApplication.java │ └── resources │ └── application.properties └── pom.xml
4.2 Maven依賴配置
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot-sentinel-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.6.3</spring-boot.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot 依賴管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud 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>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sentinel 依賴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>4.3 應(yīng)用配置文件
# application.properties spring.application.name=sentinel-demo server.port=8080 # Sentinel 控制臺(tái)地址 spring.cloud.sentinel.transport.dashboard=localhost:8080 # 取消Sentinel控制臺(tái)懶加載 spring.cloud.sentinel.eager=true # 設(shè)置應(yīng)用與Sentinel控制臺(tái)的心跳間隔時(shí)間 spring.cloud.sentinel.transport.heartbeat-interval-ms=3000
4.4 Sentinel配置類
package com.example.config;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Sentinel配置類
* 注冊(cè)SentinelResourceAspect,用于支持@SentinelResource注解
*/
@Configuration
public class SentinelConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}4.5 服務(wù)類
package com.example.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
/**
* 業(yè)務(wù)服務(wù)類
* 使用@SentinelResource注解定義資源點(diǎn)
*/
@Service
public class HelloService {
/**
* 定義一個(gè)資源點(diǎn),指定blockHandler處理限流異常
* @param name 參數(shù)
* @return 返回結(jié)果
*/
@SentinelResource(value = "sayHello", blockHandler = "sayHelloExceptionHandler")
public String sayHello(String name) {
return "Hello, " + name;
}
/**
* 定義一個(gè)資源點(diǎn),同時(shí)指定blockHandler和fallback
* blockHandler: 處理限流異常
* fallback: 處理業(yè)務(wù)異常
* @param name 參數(shù)
* @return 返回結(jié)果
*/
@SentinelResource(value = "circuitBreaker",
fallback = "circuitBreakerFallback",
blockHandler = "sayHelloExceptionHandler")
public String circuitBreaker(String name) {
// 模擬業(yè)務(wù)邏輯,當(dāng)name為"test"時(shí)拋出異常
if ("test".equals(name)) {
return "Hello, " + name;
}
throw new RuntimeException("發(fā)生異常");
}
/**
* 熔斷降級(jí)處理方法,處理業(yè)務(wù)異常
* @param name 參數(shù)
* @return 降級(jí)返回結(jié)果
*/
public String circuitBreakerFallback(String name) {
return "服務(wù)異常,熔斷降級(jí),請(qǐng)稍后重試!";
}
/**
* 限流降級(jí)處理方法,處理限流異常
* @param name 參數(shù)
* @param ex 限流異常
* @return 限流返回結(jié)果
*/
public String sayHelloExceptionHandler(String name, BlockException ex) {
return "訪問過快,限流降級(jí),請(qǐng)稍后重試!";
}
}4.6 控制器類
package com.example.controller;
import com.example.service.HelloService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 測(cè)試Sentinel的控制器
*/
@RestController
@RequestMapping("/sentinel")
public class TestSentinelController {
@Autowired
private HelloService helloService;
/**
* 測(cè)試限流功能
* @param name 參數(shù)
* @return 返回結(jié)果
*/
@GetMapping("/hello")
public String hello(@RequestParam("name") String name) {
return helloService.sayHello(name);
}
/**
* 測(cè)試熔斷功能
* @param name 參數(shù)
* @return 返回結(jié)果
*/
@GetMapping("/circuit")
public String circuitBreaker(@RequestParam("name") String name) {
return helloService.circuitBreaker(name);
}
}4.7 應(yīng)用啟動(dòng)類
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Sentinel示例應(yīng)用啟動(dòng)類
*/
@SpringBootApplication
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
}
}4.8 運(yùn)行與測(cè)試
4.8.1 下載并啟動(dòng)Sentinel控制臺(tái)
下載Sentinel控制臺(tái)jar包:
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
啟動(dòng)Sentinel控制臺(tái):
java -Dserver.port=8080 -jar sentinel-dashboard-1.8.6.jar
訪問Sentinel控制臺(tái):
http://localhost:8080
默認(rèn)用戶名和密碼都是:sentinel
4.8.2 啟動(dòng)SpringBoot應(yīng)用
啟動(dòng)應(yīng)用:
mvn spring-boot:run
測(cè)試限流功能:
http://localhost:8080/sentinel/hello?name=world
測(cè)試熔斷功能:
http://localhost:8080/sentinel/circuit?name=test
http://localhost:8080/sentinel/circuit?name=other
4.8.3 在Sentinel控制臺(tái)配置規(guī)則
登錄Sentinel控制臺(tái)后,可以看到應(yīng)用已經(jīng)注冊(cè)到控制臺(tái)
配置流控規(guī)則:
- 點(diǎn)擊"簇點(diǎn)鏈路",找到"sayHello"資源
- 點(diǎn)擊"流控"按鈕,設(shè)置QPS閾值為5
- 保存規(guī)則
配置熔斷規(guī)則:
- 點(diǎn)擊"簇點(diǎn)鏈路",找到"circuitBreaker"資源
- 點(diǎn)擊"降級(jí)"按鈕,設(shè)置異常比例閾值為0.5,時(shí)間窗口為10s
- 保存規(guī)則
測(cè)試規(guī)則效果:
- 快速刷新限流接口,當(dāng)QPS超過5時(shí),會(huì)觸發(fā)限流
- 多次訪問熔斷接口并傳入非"test"參數(shù),當(dāng)異常比例超過50%時(shí),會(huì)觸發(fā)熔斷
4.9 高級(jí)配置
4.9.1 持久化規(guī)則配置
Sentinel支持多種數(shù)據(jù)源來持久化規(guī)則配置,以下是使用文件配置的示例:
# 配置Sentinel規(guī)則持久化到文件 spring.cloud.sentinel.datasource.ds1.file.file=classpath:sentinel/flow-rule.json spring.cloud.sentinel.datasource.ds1.file.data-type=json spring.cloud.sentinel.datasource.ds1.file.rule-type=flow spring.cloud.sentinel.datasource.ds2.file.file=classpath:sentinel/degrade-rule.json spring.cloud.sentinel.datasource.ds2.file.data-type=json spring.cloud.sentinel.datasource.ds2.file.rule-type=degrade
4.9.2 Nacos配置中心持久化
# 配置Sentinel規(guī)則持久化到Nacos spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds1.nacos.data-id=sentinel-flow-rules spring.cloud.sentinel.datasource.ds1.nacos.group-id=SENTINEL_GROUP spring.cloud.sentinel.datasource.ds1.nacos.data-type=json spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848 spring.cloud.sentinel.datasource.ds2.nacos.data-id=sentinel-degrade-rules spring.cloud.sentinel.datasource.ds2.nacos.group-id=SENTINEL_GROUP spring.cloud.sentinel.datasource.ds2.nacos.data-type=json spring.cloud.sentinel.datasource.ds2.nacos.rule-type=degrade
4.9.3 自定義全局異常處理
package com.example.config;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* 自定義Sentinel全局異常處理
*/
@Configuration
public class SentinelBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
// 設(shè)置響應(yīng)類型
response.setStatus(429);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
Map<String, Object> result = new HashMap<>();
result.put("code", 429);
result.put("success", false);
if (e instanceof FlowException) {
result.put("message", "請(qǐng)求被限流了");
} else if (e instanceof DegradeException) {
result.put("message", "請(qǐng)求被降級(jí)了");
} else if (e instanceof ParamFlowException) {
result.put("message", "熱點(diǎn)參數(shù)限流");
} else if (e instanceof SystemBlockException) {
result.put("message", "系統(tǒng)規(guī)則限制");
} else if (e instanceof AuthorityException) {
result.put("message", "授權(quán)規(guī)則不通過");
} else {
result.put("message", "未知限流降級(jí)");
}
// 返回JSON數(shù)據(jù)
PrintWriter out = response.getWriter();
out.write(new ObjectMapper().writeValueAsString(result));
out.flush();
out.close();
}
}五、總結(jié)
本文詳細(xì)介紹了Sentinel的核心原理和基本功能點(diǎn),包括流量控制、熔斷降級(jí)、熱點(diǎn)參數(shù)限流、系統(tǒng)自適應(yīng)限流等,并提供了一個(gè)完整的SpringBoot整合Sentinel的案例。
Sentinel作為一個(gè)面向分布式服務(wù)架構(gòu)的流量控制組件,在微服務(wù)架構(gòu)中扮演著重要的角色。它不僅提供了豐富的流量控制策略,還提供了實(shí)時(shí)的監(jiān)控功能,可以幫助開發(fā)者更好地了解服務(wù)的運(yùn)行情況,及時(shí)發(fā)現(xiàn)和解決問題。
在實(shí)際應(yīng)用中,我們可以根據(jù)業(yè)務(wù)需求,靈活配置Sentinel的各種規(guī)則,以達(dá)到最佳的保護(hù)效果。同時(shí),Sentinel還提供了多種規(guī)則持久化的方式,可以方便地將規(guī)則存儲(chǔ)到配置中心,實(shí)現(xiàn)規(guī)則的動(dòng)態(tài)更新。
參考資料
到此這篇關(guān)于Sentinel原理與SpringBoot整合實(shí)戰(zhàn)案例講解的文章就介紹到這了,更多相關(guān)SpringBoot整合Sentinel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot?中使用Sentinel的詳細(xì)步驟
- springboot整合sentinel接口熔斷的實(shí)現(xiàn)示例
- 在SpringBoot項(xiàng)目中使用Spring Cloud Sentinel實(shí)現(xiàn)流量控制
- springboot?整合sentinel的示例代碼
- 詳解Springboot集成sentinel實(shí)現(xiàn)接口限流入門
- SpringBoot2.0+阿里巴巴Sentinel動(dòng)態(tài)限流實(shí)戰(zhàn)(附源碼)
- springboot整合sentinel的方法教程
- SpringBoot基于Sentinel在服務(wù)上實(shí)現(xiàn)接口限流
- 詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel)
- SpringBoot整合Sentinel啟動(dòng)失敗及運(yùn)行時(shí)常見錯(cuò)誤總結(jié)
相關(guān)文章
Java?關(guān)鍵字break和continue的使用說明
這篇文章主要介紹了Java?關(guān)鍵字break和continue的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
mybatis 一對(duì)多嵌套查詢的實(shí)現(xiàn)
本文主要介紹了mybatis 一對(duì)多嵌套查詢的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
Java中JDK14的新特性之JFR,JMC和JFR事件流(推薦)
JFR是一個(gè)基于事件的低開銷的分析引擎,具有高性能的后端,可以以二進(jìn)制格式編寫事件,而JMC是一個(gè)GUI工具,用于檢查JFR創(chuàng)建的數(shù)據(jù)文件。本文給大家介紹Java中JDK14的新特性之JFR,JMC和JFR事件流的相關(guān)知識(shí),感興趣的朋友一起看看吧2020-05-05
Spring集成webSocket頁面訪問404問題的解決方法
這篇文章主要介紹了Spring集成webSocket頁面訪問404問題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Intellij Idea部署OpenCV 4.0.0環(huán)境
這篇文章主要為大家詳細(xì)介紹了Intellij Idea部署OpenCV 4.0.0環(huán)境,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
java使用FuncGPT慧函數(shù)對(duì)Mybatis進(jìn)行一對(duì)一查詢映射處理
這篇文章主要介紹了java使用FuncGPT慧函數(shù)對(duì)Mybatis進(jìn)行一對(duì)一查詢映射處理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09

