最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot4使用Sentinel進(jìn)行限流的操作方法

 更新時(shí)間:2025年12月27日 14:35:48   作者:enjoy編程  
Sentinel是阿里巴巴開源的流量控制組件,用于保障微服務(wù)架構(gòu)的穩(wěn)定性,它提供了多種規(guī)則類型,本文還介紹了如何在Spring Boot 4中集成Sentinel,以及Sentinel在不同版本的Spring Boot和Spring Cloud中的兼容性情況,感興趣的朋友跟隨小編一起看看吧

Sentinel介紹

隨著微服務(wù)的流行,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要。Sentinel 是面向分布式、多語言異構(gòu)化服務(wù)架構(gòu)的流量治理組件,主要以流量為切入點(diǎn),從流量路由、流量控制、流量整形、熔斷降級、系統(tǒng)自適應(yīng)過載保護(hù)、熱點(diǎn)流量防護(hù)等多個(gè)維度來幫助開發(fā)者保障微服務(wù)的穩(wěn)定性。

Sentinel 社區(qū)正在將流量治理相關(guān)標(biāo)準(zhǔn)抽出到 OpenSergo spec 中,Sentinel 作為流量治理標(biāo)準(zhǔn)實(shí)現(xiàn)

Sentinel規(guī)則類型

針對Sentinel的規(guī)則重新學(xué)習(xí)下,詳細(xì)使用文檔參見 官方文檔

規(guī)則類型核心作用維度典型應(yīng)用場景觸發(fā)后果作用
流控規(guī)則 (Flow)限制流量 (QPS/線程數(shù))秒殺限流、防止突發(fā)流量沖垮系統(tǒng)請求被拒絕/排隊(duì)等待防刷、防過載
熔斷規(guī)則 (Degrade)依賴穩(wěn)定性 (響應(yīng)時(shí)間/異常)調(diào)用第三方接口超時(shí)、數(shù)據(jù)庫慢查詢暫停請求,快速失?。ㄈ蹟啵?/td>防雪崩、防依賴故障
熱點(diǎn)規(guī)則 (Param)參數(shù)粒度 (特定參數(shù)值)某個(gè)熱門商品被瘋狂刷,其他商品正常訪問限制特定參數(shù)的訪問頻率防熱點(diǎn)數(shù)據(jù)擊穿
系統(tǒng)規(guī)則 (System)整體負(fù)載 (CPU/Load/RT)大促期間防止機(jī)器過載,保護(hù)系統(tǒng)基線拒絕部分請求,保護(hù)機(jī)器不掛防機(jī)器掛掉
授權(quán)規(guī)則 (Auth)來源控制 (黑白名單)防止某個(gè)惡意 IP 或非法應(yīng)用調(diào)用接口允許或拒絕請求防非法調(diào)用

流控規(guī)則(Flow Control)

最常用的規(guī)則,主要用于限流,有如下2種模式

  • QPS 模式:每秒允許多少個(gè)請求通過。超過閾值則攔截。
  • 線程數(shù)模式:限制同時(shí)處理該資源的線程數(shù)量。

除了簡單的直接拒絕,它還有兩種高級策略:

  • Warm Up (預(yù)熱):比如系統(tǒng)剛啟動(dòng),像冷車一樣,不能直接拉滿油門。預(yù)熱模式會(huì)在一定時(shí)間內(nèi)逐漸將閾值從低升到高,防止瞬間流量把剛啟動(dòng)的服務(wù)打掛。
  • 排隊(duì)等待 (Queueing):不直接拒絕請求,而是讓請求按照設(shè)定的時(shí)間間隔勻速通過(像檢票口一樣),用于處理突發(fā)的脈沖流量。

熔斷規(guī)則 (Circuit Breaker)

關(guān)注服務(wù)的質(zhì)量。當(dāng)它發(fā)現(xiàn)某個(gè)服務(wù)調(diào)用“不健康”時(shí),會(huì)直接切斷連接,防止連鎖故障(雪崩)。
Sentinel 支持三種策略:

  • 慢調(diào)用比例:如果一個(gè)接口的平均響應(yīng)時(shí)間(RT)太長(比如超過 1 秒),且比例達(dá)到閾值,就熔斷。適用于對響應(yīng)速度敏感的場景。
  • 異常比例:如果請求中出現(xiàn)的異常(如拋出 RuntimeException)比例過高,就熔斷。
  • 異常數(shù):統(tǒng)計(jì)時(shí)間內(nèi)出現(xiàn)的異常總數(shù)超過閾值,直接熔斷。

熔斷是“寧可錯(cuò)殺一百,不可放過一個(gè)”的保護(hù)機(jī)制。觸發(fā)后,所有請求直接走“降級邏輯”(fallback),不再調(diào)用下游真實(shí)服務(wù),直到經(jīng)過一段“冷卻時(shí)間”后嘗試恢復(fù)

熱點(diǎn)規(guī)則 (Hotspot Param)

流控規(guī)則的高級版,它能把限流的粒度細(xì)化到方法參數(shù)級別。
通常情況下,流控是對整個(gè)接口(如 /getProduct)限流。但熱點(diǎn)規(guī)則可以做到:當(dāng)參數(shù) id=1 的時(shí)候限流 100 QPS,而 id=2 的時(shí)候不限流

關(guān)注的是“不均勻”。在實(shí)際場景中,可能只有某個(gè)特定的“爆款”商品(熱點(diǎn) key)流量巨大,導(dǎo)致數(shù)據(jù)庫壓力大。如果對整個(gè)接口限流,會(huì)誤傷其他正常的商品查詢。熱點(diǎn)規(guī)則就是為了解決這種“貧富不均”的問題

系統(tǒng)規(guī)則 (System Protection)

全局視角的規(guī)則,它不針對某個(gè)具體的接口,而是針對整個(gè)應(yīng)用實(shí)例的系統(tǒng)指標(biāo)。
它監(jiān)控的指標(biāo)包括:

  • Load(僅 Linux/Unix):系統(tǒng)平均負(fù)載。
  • CPU 使用率。
  • 入口 QPS
  • 線程數(shù)。
  • 平均 RT。
    保底”機(jī)制。通常在單機(jī)的 QPS 或負(fù)載過高時(shí)觸發(fā),目的是讓系統(tǒng)整體保持在一個(gè)穩(wěn)定的水位,防止機(jī)器直接死機(jī)。它是一種兜底的保護(hù),通常配置的閾值會(huì)比機(jī)器的極限處理能力稍微保守一點(diǎn)

授權(quán)規(guī)則 (Authority Rule)

黑白名單機(jī)制,用于控制“誰可以調(diào)用”。
它通過 SentinelContext 中的 origin(來源標(biāo)識)來判斷。通常用來識別調(diào)用方的服務(wù)名、IP 地址等。 關(guān)注的是“身份”,可以使用黑名單 或白名單限制

Spring boot 4如何集成Sentinel?

本次采用@SentinelResource + AOP 方式集成 Sentinel

添加依賴

 <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-parameter-flow-control</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.8.9</version>
        </dependency>

編寫相關(guān)的測試代碼

SentinelConfig類

@Configuration
public class SentinelConfig {
    @PostConstruct
    public void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(10);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
    @PostConstruct
    public void initDegradeRules() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); // RT threshold degrade strategy
        rule.setCount(200); // Max response time (ms)
        rule.setTimeWindow(10); // Recovery timeout period in seconds
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}

HelloWorldService

@Service
public class HelloWorldService {
    @SentinelResource(value = "HelloWorld",
        entryType = EntryType.IN,
        exceptionsToIgnore = {IllegalStateException.class},
        blockHandler = "handleBlock",
        fallback = "handleFallback")
    public String sayHello(String name) {
        return "Hello, " + name;
    }
    public String handleBlock(String name, BlockException ex) {
        return "Request blocked by Sentinel: " + ex.getClass().getSimpleName();
    }
    public String handleFallback(String name, Throwable t) {
        return "Request failed and handled by fallback: " + t.getClass().getSimpleName();
    }
}

HelloWorldController

@RestController
@RequestMapping("/api")
@Tag(name = "登錄接口")
public class HelloWorldController {
    @Autowired
    private HelloWorldService helloWorldService;
    @GetMapping("/hello")
    @Operation(summary = "hello")
    public String sayHello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return helloWorldService.sayHello(name);
    }
}
@SpringBootTest
@Slf4j
public class SentinelTest {
    @Autowired
    HelloWorldService helloWorldService;
    private AtomicInteger successCount = new AtomicInteger(0);
    private AtomicInteger blockCount = new AtomicInteger(0);
    private AtomicInteger fallbackCount = new AtomicInteger(0);
    @BeforeEach
    public void setUp() throws Exception {
        // Reset counters before each test
        successCount.set(0);
        blockCount.set(0);
        fallbackCount.set(0);
    }
    @Test
    public void testRateLimitingAndDegradation() throws InterruptedException {
        log.info("準(zhǔn)備測試...............");
        TimeUnit.SECONDS.sleep(5);
        log.info("開始測試...............");
        int numberOfThreads = 30; // Number of concurrent threads
        ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
        CountDownLatch latch = new CountDownLatch(numberOfThreads);
        for (int i = 0; i < numberOfThreads; i++) {
            executorService.submit(() -> {
                try {
                    String result = helloWorldService.sayHello("TestUser");
                    if (result.contains("blocked")) {
                        blockCount.incrementAndGet();
                    } else if (result.contains("failed")) {
                        fallbackCount.incrementAndGet();
                    } else {
                        successCount.incrementAndGet();
                    }
                } catch (Exception ex) {
                    System.out.println(ex.getMessage());
                    fallbackCount.incrementAndGet();
                } finally {
                    latch.countDown();
                }
            });
        }
        latch.await(); // Wait until all threads have completed
        log.info("Success count: " + successCount.get());
        log.info("Blocked count: " + blockCount.get());
        log.info("Fallback count: " + fallbackCount.get());
        // Assuming the flow rule is set to allow up to 20 requests per second
        assert successCount.get() <= 20 : "Number of successful requests should not exceed 20";
        assert blockCount.get() > 0 : "Some requests should be blocked due to rate limiting";
        assert fallbackCount.get() == 0 : "No requests should go to fallback under normal conditions";
        executorService.shutdown();
    }
}

啟動(dòng)程序

啟動(dòng)sentinel-dashboard

java -Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8858 -Dproject.name=sentinel-dashboard -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456  -Dserver.servlet.session.timeout=7200 -jar sentinel-dashboard-1.8.9.jar

啟動(dòng)Springboot

注意在啟動(dòng)時(shí)需要添加VM參數(shù)

-Dcsp.sentinel.dashboard.server=localhost:8858

界面展示

通過界面可以針對規(guī)則進(jìn)行修改,保存后可以立即生效

附錄

限流常見配置參數(shù)速查表

概念說明適用場景
QPS每秒查詢率大促搶購、防止刷單
線程數(shù)并發(fā)占用線程數(shù)保護(hù)慢接口不占用所有線程池
快速失敗超過閾值直接報(bào)錯(cuò)默認(rèn)策略,簡單粗暴
Warm Up預(yù)熱模式,閾值緩慢升高系統(tǒng)剛啟動(dòng),防止瞬間高流量壓垮
排隊(duì)等待請求勻速通過,處理不急的請求訂單創(chuàng)建等需要削峰填谷的場景

Token Server Cluster 部署方式對比

特性嵌入模式 (Embedded)獨(dú)立模式 (Alone)
部署成本 (利用現(xiàn)有資源) (需要獨(dú)立機(jī)器)
隔離性差 (與業(yè)務(wù)爭搶資源) (完全隔離)
適用場景中小規(guī)模集群、對成本敏感超大規(guī)模集群、核心中間件、全局限流
容災(zāi)能力依賴應(yīng)用集群的穩(wěn)定性強(qiáng) (通常有主從熱備)
運(yùn)維難度簡單較復(fù)雜 (需維護(hù) Server 集群)

與springboot及springcloud版本對應(yīng)關(guān)系

Spring Boot 版本對應(yīng)的 Spring Cloud Alibaba (SCA) 版本對應(yīng)的 Sentinel 版本狀態(tài)
2.3.x2.2.x.RELEASE1.7.x / 1.8.0舊版,已不再主推
2.4.x, 2.5.x, 2.6.x, 2.7.x2021.x (如 2021.0.5.0)1.8.5 / 1.8.6目前最主流的生產(chǎn)環(huán)境組合
3.0.x, 3.1.x2022.0.0.0 (or 2022.0.0.0-RC2)1.8.6 (有限支持)注意:原生 Web 適配器不支持,需用 Gateway 或特定適配
  • Sentinel(通過 Spring Cloud Alibaba)實(shí)際上支持 Spring Boot 2.x 的全系版本
  • Spring Boot 3.0 的變化:Spring Boot 3.0 強(qiáng)制要求 Java 17+,并且將底層的 javax.servlet (Java EE) 遷移為了 jakarta.servlet (Jakarta EE)。
  • Sentinel 對 Spring Boot 的支持在 3.0 上遇到了“斷層”,這才是目前版本選擇的核心痛點(diǎn)
  • Sentinel 的現(xiàn)狀
    • Sentinel-core / sentinel-web-servlet:目前的主流穩(wěn)定版本(如 1.8.x)底層依然使用的是 javax.servlet.Filter。
    • sentinel-spring-webmvc-adapter 目前使用的 springboot 2.5.x版本,servlet.api版本是3.1.0
    • 不兼容:這意味著,如果你直接使用原生的 sentinel-web-servlet 依賴,它是無法運(yùn)行在 Spring Boot 3.0 環(huán)境下的,會(huì)報(bào) ClassNotFoundException(找不到 javax 包)

到此這篇關(guān)于Spring Boot4使用Sentinel進(jìn)行限流的操作方法的文章就介紹到這了,更多相關(guān)springboot sentinel限流內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring框架中的本地緩存之spring cache基本使用詳解

    spring框架中的本地緩存之spring cache基本使用詳解

    Spring Cache 是 Spring 提供的一整套的緩存解決方案,它提供了一整套的接口和代碼規(guī)范、配置、注解等,這樣它就可以整合各種緩存方案了,本文給大家介紹spring框架中的本地緩存之spring cache基本使用,感興趣的朋友一起看看吧
    2025-05-05
  • 如何在Java中調(diào)用python文件執(zhí)行詳解

    如何在Java中調(diào)用python文件執(zhí)行詳解

    豐富的第三方庫使得python非常適合用于進(jìn)行數(shù)據(jù)分析,最近在項(xiàng)目中就涉及到j(luò)ava調(diào)用python實(shí)現(xiàn)的算法,下面這篇文章主要給大家介紹了關(guān)于如何在Java中調(diào)用python文件執(zhí)行的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):棧

    java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):棧

    這篇文章主要介紹了Java的數(shù)據(jù)解構(gòu)基礎(chǔ),希望對廣大的程序愛好者有所幫助,同時(shí)祝大家有一個(gè)好成績,需要的朋友可以參考下,希望能給你帶來幫助
    2021-07-07
  • Java如何導(dǎo)出包含多個(gè)Sheet的Excel文件

    Java如何導(dǎo)出包含多個(gè)Sheet的Excel文件

    這篇文章主要為大家詳細(xì)介紹了Java如何導(dǎo)出包含多個(gè)Sheet的Excel文件,文中一共介紹了兩種實(shí)現(xiàn)方法,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-07-07
  • Java中淺拷貝和深拷貝詳解

    Java中淺拷貝和深拷貝詳解

    大家好,本篇文章主要講的是Java中淺拷貝和深拷貝詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 解決springboot服務(wù)注冊到Eureka,端口總是默認(rèn)8080,自己配置端口不生效問題

    解決springboot服務(wù)注冊到Eureka,端口總是默認(rèn)8080,自己配置端口不生效問題

    作者接手一個(gè)SpringCloud項(xiàng)目時(shí)發(fā)現(xiàn)Eureka注冊的服務(wù)端口與實(shí)際Ribbon調(diào)用的實(shí)例端口不一致,通過查閱資料發(fā)現(xiàn)是Eureka讀取server.port不生效,通過在配置文件里添加nonSecurePort參數(shù)即可強(qiáng)制綁定端口
    2026-05-05
  • 詳解spring與jdbc整合操作

    詳解spring與jdbc整合操作

    這篇文章主要為大家詳細(xì)介紹了spring與jdbc整合操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Sentinel中三種流控模式的使用詳解

    Sentinel中三種流控模式的使用詳解

    這篇文章主要為大家詳細(xì)介紹了Sentinel中三種流控模式(預(yù)熱模式,排隊(duì)等待模式和熱點(diǎn)規(guī)則)的使用,文中的示例代碼講解詳細(xì),感興趣的可以了解下
    2023-08-08
  • SpringBoot集成Swagger2生成接口文檔的方法示例

    SpringBoot集成Swagger2生成接口文檔的方法示例

    我們提供Restful接口的時(shí)候,API文檔是尤為的重要,它承載著對接口的定義,描述等,本文主要介紹了SpringBoot集成Swagger2生成接口文檔的方法示例,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • java單向鏈表的實(shí)現(xiàn)實(shí)例

    java單向鏈表的實(shí)現(xiàn)實(shí)例

    java單向鏈表的實(shí)現(xiàn)實(shí)例。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10

最新評論

商城县| 涞源县| 镇坪县| 鹤壁市| 洪泽县| 瓮安县| 莱西市| 蚌埠市| 平顶山市| 广平县| 阳新县| 云龙县| 城口县| 调兵山市| 安龙县| 盐源县| 丹江口市| 苏尼特右旗| 兴化市| 铜山县| 合肥市| 利津县| 微博| 墨玉县| 奉贤区| 获嘉县| 遂昌县| 义乌市| 克山县| 博客| 襄汾县| 梁河县| 五台县| 阿鲁科尔沁旗| 佳木斯市| 保山市| 开鲁县| 吉水县| 天全县| 班戈县| 民勤县|