欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java常見(jiàn)的限流方案及實(shí)現(xiàn)方法

 更新時(shí)間:2025年05月23日 08:30:30   作者:SHENKEM  
高并發(fā)場(chǎng)景中限流是保護(hù)系統(tǒng)的重要手段,涵蓋計(jì)數(shù)器、滑動(dòng)窗口、漏桶、令牌桶等算法,這篇文章主要介紹了Java常見(jiàn)的限流方案及實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

在高并發(fā)場(chǎng)景中,限流(Rate Limiting) 是一種重要的保護(hù)機(jī)制,用于控制系統(tǒng)的請(qǐng)求流量,避免系統(tǒng)過(guò)載。以下是常見(jiàn)的限流方案及其 Java 實(shí)現(xiàn)。

1. 限流的常見(jiàn)算法

1.1 計(jì)數(shù)器算法

  • 原理:在固定時(shí)間窗口內(nèi)統(tǒng)計(jì)請(qǐng)求次數(shù),超過(guò)閾值則拒絕請(qǐng)求。

  • 優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單。

  • 缺點(diǎn):無(wú)法應(yīng)對(duì)突發(fā)流量。

1.2 滑動(dòng)窗口算法

  • 原理:將時(shí)間窗口劃分為多個(gè)小窗口,統(tǒng)計(jì)最近一段時(shí)間內(nèi)的請(qǐng)求次數(shù)。

  • 優(yōu)點(diǎn):比計(jì)數(shù)器算法更平滑。

  • 缺點(diǎn):實(shí)現(xiàn)復(fù)雜。

1.3 漏桶算法

  • 原理:請(qǐng)求以固定速率流出,超過(guò)桶容量的請(qǐng)求被丟棄或等待。

  • 優(yōu)點(diǎn):平滑流量。

  • 缺點(diǎn):無(wú)法應(yīng)對(duì)突發(fā)流量。

1.4 令牌桶算法

  • 原理:以固定速率生成令牌,請(qǐng)求需要獲取令牌才能被處理。

  • 優(yōu)點(diǎn):支持突發(fā)流量。

  • 缺點(diǎn):實(shí)現(xiàn)復(fù)雜。

2. 限流方案的 Java 實(shí)現(xiàn)

以下是基于 計(jì)數(shù)器算法 和 令牌桶算法 的 Java 實(shí)現(xiàn)示例。

2.1 計(jì)數(shù)器算法實(shí)現(xiàn)

import java.util.concurrent.atomic.AtomicInteger;

public class CounterRateLimiter {
    private final int limit; // 限流閾值
    private final long interval; // 時(shí)間窗口(毫秒)
    private final AtomicInteger counter; // 計(jì)數(shù)器
    private long lastResetTime; // 上次重置時(shí)間

    public CounterRateLimiter(int limit, long interval) {
        this.limit = limit;
        this.interval = interval;
        this.counter = new AtomicInteger(0);
        this.lastResetTime = System.currentTimeMillis();
    }

    public boolean tryAcquire() {
        long now = System.currentTimeMillis();
        if (now - lastResetTime > interval) {
            // 重置計(jì)數(shù)器
            counter.set(0);
            lastResetTime = now;
        }
        // 判斷是否超過(guò)閾值
        return counter.incrementAndGet() <= limit;
    }

    public static void main(String[] args) throws InterruptedException {
        CounterRateLimiter limiter = new CounterRateLimiter(10, 1000); // 每秒限流 10 次
        for (int i = 0; i < 20; i++) {
            System.out.println("請(qǐng)求 " + i + ": " + (limiter.tryAcquire() ? "通過(guò)" : "被限流"));
            Thread.sleep(100); // 模擬請(qǐng)求間隔
        }
    }
}

2.2 令牌桶算法實(shí)現(xiàn)

import java.util.concurrent.atomic.AtomicLong;

public class TokenBucketRateLimiter {
    private final long capacity; // 桶容量
    private final long rate; // 令牌生成速率(令牌/毫秒)
    private final AtomicLong tokens; // 當(dāng)前令牌數(shù)量
    private long lastRefillTime; // 上次補(bǔ)充令牌時(shí)間

    public TokenBucketRateLimiter(long capacity, long rate) {
        this.capacity = capacity;
        this.rate = rate;
        this.tokens = new AtomicLong(capacity);
        this.lastRefillTime = System.currentTimeMillis();
    }

    public boolean tryAcquire() {
        refillTokens(); // 補(bǔ)充令牌
        long currentTokens = tokens.get();
        if (currentTokens > 0) {
            return tokens.decrementAndGet() >= 0;
        }
        return false;
    }

    private void refillTokens() {
        long now = System.currentTimeMillis();
        long elapsedTime = now - lastRefillTime;
        long newTokens = elapsedTime * rate; // 計(jì)算新增令牌數(shù)
        if (newTokens > 0) {
            lastRefillTime = now;
            tokens.updateAndGet(old -> Math.min(capacity, old + newTokens)); // 更新令牌數(shù)
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TokenBucketRateLimiter limiter = new TokenBucketRateLimiter(10, 1); // 桶容量 10,每秒生成 1 個(gè)令牌
        for (int i = 0; i < 20; i++) {
            System.out.println("請(qǐng)求 " + i + ": " + (limiter.tryAcquire() ? "通過(guò)" : "被限流"));
            Thread.sleep(100); // 模擬請(qǐng)求間隔
        }
    }
}

3. 使用 Guava 的 RateLimiter

Google Guava 提供了 RateLimiter 類,基于令牌桶算法實(shí)現(xiàn)限流。

3.1 添加依賴

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

運(yùn)行 HTML

3.2 使用示例

import com.google.common.util.concurrent.RateLimiter;

public class GuavaRateLimiterExample {
    public static void main(String[] args) throws InterruptedException {
        RateLimiter limiter = RateLimiter.create(1.0); // 每秒限流 1 次
        for (int i = 0; i < 10; i++) {
            System.out.println("請(qǐng)求 " + i + ": " + (limiter.tryAcquire() ? "通過(guò)" : "被限流"));
            Thread.sleep(300); // 模擬請(qǐng)求間隔
        }
    }
}

4. 限流方案的選擇

算法優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
計(jì)數(shù)器實(shí)現(xiàn)簡(jiǎn)單無(wú)法應(yīng)對(duì)突發(fā)流量簡(jiǎn)單限流場(chǎng)景
滑動(dòng)窗口比計(jì)數(shù)器更平滑實(shí)現(xiàn)復(fù)雜需要平滑限流的場(chǎng)景
漏桶平滑流量無(wú)法應(yīng)對(duì)突發(fā)流量需要嚴(yán)格控制流量的場(chǎng)景
令牌桶支持突發(fā)流量實(shí)現(xiàn)復(fù)雜需要支持突發(fā)流量的場(chǎng)景
Guava簡(jiǎn)單易用,功能強(qiáng)大依賴第三方庫(kù)需要快速實(shí)現(xiàn)限流的場(chǎng)景

5. 總結(jié)

  • 限流是保護(hù)系統(tǒng)的重要手段,常見(jiàn)的限流算法包括計(jì)數(shù)器、滑動(dòng)窗口、漏桶和令牌桶。

  • Java 中可以通過(guò)自定義實(shí)現(xiàn)或使用 Guava 的 RateLimiter 實(shí)現(xiàn)限流。

  • 根據(jù)業(yè)務(wù)需求選擇合適的限流方案,確保系統(tǒng)的穩(wěn)定性和高可用性。

通過(guò)以上內(nèi)容,可以輕松掌握限流的實(shí)現(xiàn)方法!

到此這篇關(guān)于Java常見(jiàn)的限流方案及實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java限流方案內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java8 Collectors.toMap的坑

    Java8 Collectors.toMap的坑

    這篇文章主要介紹了Java8 Collectors.toMap的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java多線程中的ThreadPoolExecutor使用解析

    Java多線程中的ThreadPoolExecutor使用解析

    這篇文章主要介紹了Java多線程中的ThreadPoolExecutor使用解析,作為線程池的緩沖,當(dāng)新增線程超過(guò)maximumPoolSize時(shí),會(huì)將新增線程暫時(shí)存放到該隊(duì)列中,需要的朋友可以參考下
    2023-12-12
  • 關(guān)于mybatis-plus插件使用時(shí)的一些問(wèn)題小結(jié)

    關(guān)于mybatis-plus插件使用時(shí)的一些問(wèn)題小結(jié)

    這篇文章主要給大家介紹了關(guān)于mybatis-plus插件使用時(shí)的一些問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • SpringBoot應(yīng)用jar包啟動(dòng)原理詳解

    SpringBoot應(yīng)用jar包啟動(dòng)原理詳解

    本文主要介紹了SpringBoot應(yīng)用jar包啟動(dòng)原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • Eclipse maven項(xiàng)目lombok安裝配置圖解

    Eclipse maven項(xiàng)目lombok安裝配置圖解

    這篇文章主要介紹了Eclipse maven項(xiàng)目lombok安裝配置圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 初識(shí)Java基礎(chǔ)之?dāng)?shù)據(jù)類型與運(yùn)算符

    初識(shí)Java基礎(chǔ)之?dāng)?shù)據(jù)類型與運(yùn)算符

    Java是一種強(qiáng)類型語(yǔ)言,每個(gè)變量都必須聲明其數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于Java基礎(chǔ)之?dāng)?shù)據(jù)類型與運(yùn)算符的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • 解讀Spring?Bean的作用域

    解讀Spring?Bean的作用域

    這篇文章主要介紹了解讀Spring?Bean的作用域,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Java用鄰接表存儲(chǔ)圖的示例代碼

    Java用鄰接表存儲(chǔ)圖的示例代碼

    鄰接表是圖的一種鏈?zhǔn)酱鎯?chǔ)方法,其數(shù)據(jù)結(jié)構(gòu)包括兩部分:節(jié)點(diǎn)和鄰接點(diǎn)。本文將用鄰接表實(shí)現(xiàn)存儲(chǔ)圖,感興趣的小伙伴可以了解一下
    2022-06-06
  • Java?阻塞隊(duì)列BlockingQueue詳解

    Java?阻塞隊(duì)列BlockingQueue詳解

    本文詳細(xì)介紹了BlockingQueue家庭中的所有成員,包括他們各自的功能以及常見(jiàn)使用場(chǎng)景,通過(guò)實(shí)例代碼介紹了Java?阻塞隊(duì)列BlockingQueue的相關(guān)知識(shí),需要的朋友可以參考下
    2022-06-06
  • Spring?Boot?集成PageHelper的使用方法

    Spring?Boot?集成PageHelper的使用方法

    這篇文章主要介紹了Spring?Boot?集成PageHelper的使用方法,文章內(nèi)容圍繞主題展開詳細(xì)介紹,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-04-04

最新評(píng)論