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

SpringBoot實(shí)現(xiàn)接口限流的常用方案

 更新時(shí)間:2025年08月19日 08:34:14   作者:昵稱為空C  
本文主要介紹SpringBoot項(xiàng)目的接口限流方案,市面上常用有2種限流方案漏桶和令牌桶,大家常用的都是令牌桶,本文也只實(shí)現(xiàn)了令牌桶的方案,需要的朋友可以參考下

漏桶和令牌桶說(shuō)明

漏桶和令牌桶是最常用的兩種限流算法,核心差異如下:

?特性??漏桶限流(Leaky Bucket)???令牌桶限流(Token Bucket)??
?核心邏輯?固定速率處理請(qǐng)求(“漏水”),桶緩沖突發(fā)請(qǐng)求固定速率生成令牌,請(qǐng)求需獲取令牌才能處理
?輸出速率?嚴(yán)格固定(等于漏水速率)允許突發(fā)(最大為桶容量 + 新生成的令牌數(shù))
?突發(fā)容忍度?不允許突發(fā)(超過(guò)桶容量的請(qǐng)求直接拒絕)允許突發(fā)(桶中令牌足夠時(shí),可一次性處理多個(gè)請(qǐng)求)
?資源利用率?可能較低(即使系統(tǒng)空閑,也需按固定速率處理)較高(系統(tǒng)空閑時(shí)可積累令牌,突發(fā)時(shí)快速處理)
?典型場(chǎng)景?嚴(yán)格要求速率穩(wěn)定(如網(wǎng)絡(luò)流量整形)允許一定突發(fā)(如 API 接口限流)

項(xiàng)目基礎(chǔ)配置

pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.48.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>33.4.8-jre</version>
        </dependency>
    </dependencies>

application.yml

spring:
  data:
    redis:
      host: redis
      port: 6379

啟動(dòng)類

@SpringBootApplication
public class RateLimitApplication {

    public static void main(String[] args) {
        SpringApplication.run(RateLimitApplication.class, args);
    }
}

基于Redisson的令牌桶

在分布式系統(tǒng)中,使用 Redisson 實(shí)現(xiàn)并發(fā)限流是一種常見(jiàn)且高效的方式

RateType限流鍵(key)的設(shè)計(jì)

  • OVERALL模式?:限流鍵需全局唯一(如 global_api_limit),確保所有請(qǐng)求共享同一個(gè)桶。
  • PER_CLIENT模式?:限流鍵需能唯一標(biāo)識(shí)客戶端(如 user:${userId}ip:${clientIp}),確保每個(gè)客戶端獨(dú)立使用自己的桶。
@Slf4j
@RestController
@RequestMapping(value = "redisson/rate-limit")
public class RedissonRateLimitController {

    @Autowired
    private RedissonClient redissonClient;

    @PostMapping("create-order")
    public Object createOrder(String info){
        RRateLimiter rateLimiter = getLimiter();
        boolean b = rateLimiter.tryAcquire();
        if(b) {
            log.info("允許訪問(wèn)");
            return "SUCCESS";
        }
        log.warn("限流了");
        throw new RuntimeException("請(qǐng)求太火爆");
    }

    /**
     * 獲取限流器
     * @return
     */
    private RRateLimiter getLimiter() {
        RRateLimiter rateLimiter = redissonClient.getRateLimiter("create-order");
        rateLimiter.trySetRate(RateType.PER_CLIENT, 20, Duration.ofSeconds(5L));
        return rateLimiter;
    }

}

測(cè)試結(jié)果

我單線程請(qǐng)求了8S,請(qǐng)求成功40個(gè)

Guava的實(shí)現(xiàn)

Guava 的 RateLimiter是單機(jī)環(huán)境下基于令牌桶算法的輕量級(jí)限流工具,適用于控制接口請(qǐng)求頻率、資源訪問(wèn)速率或任務(wù)執(zhí)行頻率等場(chǎng)景。以下是不同場(chǎng)景下的使用案例,包含基礎(chǔ)用法、高級(jí)特性及實(shí)際業(yè)務(wù)集成。

接口說(shuō)明

  • RateLimiter.create(10.0):創(chuàng)建一個(gè)每秒生成 10 個(gè)令牌的限流器(即允許每秒 10 個(gè)請(qǐng)求)。
  • RateLimiter rateLimiter = RateLimiter.create(20.0, 5, TimeUnit.SECONDS): //創(chuàng)建預(yù)熱限流器:目標(biāo)速率 20 個(gè)/秒,預(yù)熱時(shí)間 5 秒(從 2 個(gè)/秒逐步提升到 20 個(gè)/秒)
  • rateLimiter.acquire(1):阻塞等待獲取 1 個(gè)令牌(若當(dāng)前無(wú)令牌,會(huì)等待直到新令牌生成)。返回值為等待時(shí)間(秒)
  • rateLimiter.tryAcquire(long permits, long timeout, TimeUnit unit):非阻塞獲取

具體代碼

@Slf4j
@RestController
@RequestMapping(value = "guava/rate-limit")
public class GuavaRateLimitController {

    private static final RateLimiter rateLimiter = RateLimiter.create(5);

    @PostMapping("create-order")
    public Object createOrder(String info){
        boolean b = rateLimiter.tryAcquire();
        if(b) {
            log.info("允許訪問(wèn)");
            return "SUCCESS";
        }
        log.warn("限流了");
        throw new RuntimeException("請(qǐng)求太火爆");
    }


}

結(jié)果

8s內(nèi)成功訪問(wèn)45個(gè)請(qǐng)求

基于nginx的限流

Nginx 限流核心模塊:ngx_http_limit_req_module

Nginx 內(nèi)置的 ngx_http_limit_req_module基于漏桶算法實(shí)現(xiàn)限流,通過(guò)以下兩個(gè)核心指令控制:

  • limit_req_zone:定義限流的共享內(nèi)存區(qū)和基礎(chǔ)速率。
  • limit_req:在具體 locationserver塊中應(yīng)用限流規(guī)則。

(1)定義限流共享內(nèi)存區(qū)(limit_req_zone)

在 Nginx 主配置文件(nginx.conf)的 http塊中,定義共享內(nèi)存區(qū)存儲(chǔ)限流狀態(tài):

http {
    # 定義限流共享內(nèi)存區(qū)(名稱=one,大小=10MB,速率=10請(qǐng)求/秒)
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

    # 其他全局配置...
    include       mime.types;
    default_type  application/octet-stream;
}
  • $binary_remote_addr:限流的鍵(基于客戶端 IP 地址)。
  • zone=one:10m:共享內(nèi)存區(qū)名稱為 one,大小為 10MB(根據(jù)客戶端數(shù)量調(diào)整,10MB 約支持 16 萬(wàn) IP)。
  • rate=10r/s:基礎(chǔ)速率(每秒允許 10 個(gè)請(qǐng)求)。

(2)在 server或 location中應(yīng)用限流規(guī)則

在需要限流的站點(diǎn)配置(如 server塊)中,使用 limit_req指令應(yīng)用規(guī)則,并設(shè)置被限流時(shí)的響應(yīng):

server {
    listen       80;
    server_name  example.com;

    location /api/ {
        # 應(yīng)用限流規(guī)則(使用上面定義的 zone=one)
        limit_req zone=one burst=20 nodelay;  # burst=突發(fā)容量,nodelay=不等待直接拒絕
        
        # 被限流時(shí)返回 429 狀態(tài)碼,并跳轉(zhuǎn)到自定義錯(cuò)誤頁(yè)
        limit_req_status_code 429;
        error_page 429 /custom_limit_msg;

        # 正常請(qǐng)求的反向代理(示例)
        proxy_pass http://backend_server;
    }

    # 自定義限流消息體(返回 JSON)
    location = /custom_limit_msg {
        internal;  # 僅內(nèi)部訪問(wèn),禁止外部直接請(qǐng)求
        add_header Content-Type application/json;
        return 429 '{"code": 429, "message": "請(qǐng)求過(guò)于頻繁,請(qǐng)稍后再試"}';
    }
}

關(guān)鍵參數(shù)說(shuō)明

參數(shù)/指令含義
limit_req_zone定義限流的共享內(nèi)存區(qū)、鍵(如 IP)和基礎(chǔ)速率(rate=10r/s表示每秒 10 個(gè)請(qǐng)求)。
burst突發(fā)容量(允許短時(shí)間內(nèi)超過(guò)基礎(chǔ)速率的請(qǐng)求數(shù)),例如 burst=20表示最多允許 20 個(gè)突發(fā)請(qǐng)求。
nodelay若啟用,被限流的請(qǐng)求直接拒絕?(不等待);若禁用(默認(rèn)),請(qǐng)求會(huì)等待直到令牌可用。
limit_req_status_code設(shè)置被限流時(shí)的 HTTP 狀態(tài)碼(如 429 Too Many Requests)。
error_page自定義限流時(shí)的響應(yīng)內(nèi)容(如返回 JSON 消息體)。

高級(jí)限流場(chǎng)景

1. 按用戶 ID 限流

若需按用戶 ID 限流(如防止惡意用戶高頻請(qǐng)求),可將限流鍵改為用戶 ID(需前端傳遞 X-User-ID頭):

http {
    # 限流鍵為 X-User-ID 頭的值(需確保頭存在)
    limit_req_zone $http_x_user_id zone=user_limit:10m rate=5r/s;

    server {
        location /api/user/ {
            # 校驗(yàn) X-User-ID 頭是否存在,不存在則拒絕
            if ($http_x_user_id = "") {
                return 400 "Missing X-User-ID header";
            }
            
            # 應(yīng)用限流(鍵為用戶 ID)
            limit_req zone=user_limit burst=10 nodelay;
            limit_req_status_code 429;
            error_page 429 /custom_limit_msg;
            
            proxy_pass http://backend_server;
        }
    }
}

以上就是SpringBoot實(shí)現(xiàn)接口限流的常用方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接口限流的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 學(xué)會(huì)Java字節(jié)碼指令,成為技術(shù)大佬

    學(xué)會(huì)Java字節(jié)碼指令,成為技術(shù)大佬

    Java 字節(jié)碼指令是 JVM 體系中非常難啃的一塊硬骨頭,我估計(jì)有些讀者會(huì)有這樣的疑惑,“Java 字節(jié)碼難學(xué)嗎?我能不能學(xué)會(huì)?。俊北疚膸ьI(lǐng)大家一探究竟,幫助大家搞懂java底層代碼如何執(zhí)行
    2021-08-08
  • Java NIO框架Netty簡(jiǎn)單使用的示例

    Java NIO框架Netty簡(jiǎn)單使用的示例

    本篇文章主要介紹了Java NIO框架Netty簡(jiǎn)單使用的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 詳解基于MybatisPlus兩步實(shí)現(xiàn)多租戶方案

    詳解基于MybatisPlus兩步實(shí)現(xiàn)多租戶方案

    這篇文章主要介紹了詳解基于MybatisPlus兩步實(shí)現(xiàn)多租戶方案,本文分兩步,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Spring Data JPA踩坑記錄(@id @GeneratedValue)

    Spring Data JPA踩坑記錄(@id @GeneratedValue)

    這篇文章主要介紹了Spring Data JPA踩坑記錄(@id @GeneratedValue),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 一篇文章帶你深入了解Java基礎(chǔ)(2)

    一篇文章帶你深入了解Java基礎(chǔ)(2)

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Java 深入探究講解工廠方法模式

    Java 深入探究講解工廠方法模式

    工廠方法模式(FACTORY METHOD)是一種常用的類創(chuàng)建型設(shè)計(jì)模式,此模式的核心精神是封裝類中變化的部分,提取其中個(gè)性化善變的部分為獨(dú)立類,通過(guò)依賴注入以達(dá)到解耦、復(fù)用和方便后期維護(hù)拓展的目的。它的核心結(jié)構(gòu)有四個(gè)角色,分別是抽象工廠、具體工廠、抽象產(chǎn)品、具體產(chǎn)品
    2022-04-04
  • java多線程三種上鎖方式小結(jié)

    java多線程三種上鎖方式小結(jié)

    本文主要介紹了java多線程三種上鎖方式小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • java性能火焰圖的生成實(shí)踐

    java性能火焰圖的生成實(shí)踐

    文章介紹async-profiler這一Java性能分析工具,可低開(kāi)銷(xiāo)生成火焰圖,幫助定位CPU飆升、內(nèi)存泄露等問(wèn)題,涵蓋準(zhǔn)備程序、生成數(shù)據(jù)及展示三個(gè)核心步驟,適合解決線上性能瓶頸
    2025-07-07
  • 一文詳解MQ消息丟失問(wèn)題的5種解決方案

    一文詳解MQ消息丟失問(wèn)題的5種解決方案

    有些小伙伴在工作中,一提到消息隊(duì)列就覺(jué)得很簡(jiǎn)單,但真正遇到線上消息丟失時(shí),排查起來(lái)卻讓人抓狂,今天這篇文章,專門(mén)跟大家一起聊聊這個(gè)話題,希望對(duì)你會(huì)有所幫助
    2025-10-10
  • SpringBoot如何集成Token

    SpringBoot如何集成Token

    文章介紹了如何使用jjwt插件實(shí)現(xiàn)Token的生成和校驗(yàn),該插件可以直接與SpringBoot集成,Token由三部分組成,分別是header、payload和signature,通過(guò)在請(qǐng)求頭中傳遞Token,后端可以驗(yàn)證其合法性,從而提高安全性
    2025-01-01

最新評(píng)論

双牌县| 康马县| 景东| 伊宁市| 金昌市| 剑河县| 鄂托克旗| 泰来县| 浦北县| 霍城县| 海盐县| 张家界市| 沙田区| 大兴区| 菏泽市| 土默特右旗| 海林市| 托克托县| 通化县| 翼城县| 岫岩| 交城县| 泾源县| 汉沽区| 伊宁市| 云龙县| 雷州市| 南陵县| 清徐县| 陇川县| 开封县| 六安市| 彰化市| 齐河县| 钟山县| 双柏县| 新巴尔虎右旗| 绥阳县| 建湖县| 巴青县| 安图县|