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

基于SpringBoot實現(xiàn)網(wǎng)絡限速功能

 更新時間:2026年04月01日 08:36:30   作者:小碼哥_常  
為了實現(xiàn)網(wǎng)絡限速,業(yè)內有很多行之有效的策略,每種都有其獨特的優(yōu)勢和適用場景,接下來我就給大家介紹 4 種常見的限速策略,大家可以根據(jù)需要自行選擇

一、為啥要網(wǎng)絡限速?

在當今這個數(shù)字化時代,網(wǎng)絡服務就像我們生活中的水電一樣不可或缺,而網(wǎng)絡限速則是保障這些服務穩(wěn)定、高效運行的關鍵一環(huán)。它能確保在各種復雜的網(wǎng)絡環(huán)境下,服務的性能不會受到太大影響,為用戶提供穩(wěn)定的體驗。

先來講講抵御惡意攻擊。在互聯(lián)網(wǎng)這個廣闊的世界里,并非所有的訪問都是善意的。惡意爬蟲就像不請自來的小偷,在未經授權的情況下,大量抓取網(wǎng)站數(shù)據(jù),不僅會消耗大量的網(wǎng)絡帶寬,還可能導致服務器資源被耗盡,使正常用戶無法訪問。還有 CC(Challenge Collapsar)攻擊,攻擊者通過控制大量傀儡機,向目標服務器發(fā)送海量的請求,試圖耗盡服務器的資源,使其癱瘓。這就好比一群人在瘋狂地擠一扇門,讓真正有需要進門的人被擋在外面。而通過網(wǎng)絡限速,我們可以對單位時間內的請求數(shù)量或流量進行限制,當檢測到某個 IP 或用戶的訪問頻率異常高時,直接攔截這些非法請求,就像在門口設置了一個保安,攔住那些不懷好意的人,從而有效保護服務器的安全。

再談談應對流量峰值?,F(xiàn)在的電商平臺經常會舉辦各種促銷活動,像 “雙 11”“618” 這樣的購物狂歡節(jié),大量用戶會在同一時間涌入平臺進行搶購。這就好比一場洪水突然來襲,如果服務器沒有任何防護措施,很容易就會被這突如其來的巨大流量沖垮。網(wǎng)絡限速就像是一個堅固的堤壩,通過削峰填谷的方式,將瞬間的高峰流量進行合理分配,讓流量平穩(wěn)地進入服務系統(tǒng)。比如,限制每個用戶每秒只能發(fā)起一定數(shù)量的請求,或者限制整個系統(tǒng)每秒的總請求數(shù),這樣可以避免服務器因為瞬間承受過多壓力而崩潰,確保所有用戶都能有機會參與活動,享受服務。

最后看看保護核心資源。很多服務都依賴于數(shù)據(jù)庫、緩存、第三方接口等核心資源。當大量高頻請求穿透到這些下游組件時,就像無數(shù)人同時去爭奪有限的資源,很容易導致這些組件不堪重負,引發(fā)級聯(lián)故障。比如,一個電商系統(tǒng)的訂單查詢接口,如果沒有限速,可能會有大量用戶同時請求,導致數(shù)據(jù)庫負載過高,不僅訂單查詢功能無法正常使用,還可能影響到其他依賴數(shù)據(jù)庫的功能,如商品展示、庫存更新等。通過網(wǎng)絡限速,我們可以限制對這些核心資源的訪問頻率,保護它們不被過度使用,就像給資源加上了一把鎖,只有在允許的情況下才能訪問,從而保證整個服務系統(tǒng)的穩(wěn)定運行。

二、常見限速策略大盤點

為了實現(xiàn)網(wǎng)絡限速,業(yè)內有很多行之有效的策略,每種都有其獨特的優(yōu)勢和適用場景,接下來我就給大家介紹 4 種常見的限速策略。

固定窗口計數(shù)器

固定窗口計數(shù)器算法是一種簡單直觀的限流方法。在這種算法中,我們會設定一個固定的時間窗口,比如 1 秒,然后在這個窗口內對請求進行計數(shù)。每來一個請求,計數(shù)器就加 1 ,當計數(shù)器達到設定的閾值時,后續(xù)的請求就會被拒絕,直到這個時間窗口結束,計數(shù)器才會清零,開始下一輪計數(shù)。

假設我們設置一個接口 1 秒內最多允許 100 次請求。一開始,計數(shù)器 count 為 0,每收到一個請求,count 就加 1。在這 1 秒內,如果 count 小于等于 100,請求可以正常訪問;一旦 count 超過 100,后續(xù)的請求就會被拒絕。當這 1 秒過去后,count 重置為 0,重新開始計數(shù)。這種算法的優(yōu)點是實現(xiàn)起來非常簡單,容易理解和部署。但它有一個明顯的缺陷,就是在窗口切換的瞬間,可能會出現(xiàn)突發(fā)流量問題。比如說,在 1 秒的時間窗口內,前 100 毫秒就來了 100 個請求,滿足閾值條件都被處理了,那么在接下來的 900 毫秒內,即使系統(tǒng)很空閑,再有請求也會被拒絕。更糟糕的是,在窗口切換時,如果上一個窗口最后 100 毫秒來了 100 個請求,而下一個窗口的前 100 毫秒又來 100 個請求,那么在這 200 毫秒內,系統(tǒng)就需要處理 200 個請求,遠遠超出了我們預期的每秒 100 次的限制,這就是所謂的 “突刺現(xiàn)象” 和 “臨界問題”,很可能導致系統(tǒng)負載過高甚至崩潰。

滑動窗口計數(shù)器

為了解決固定窗口計數(shù)器算法的 “突刺現(xiàn)象” 和 “臨界問題”,滑動窗口計數(shù)器算法應運而生。這種算法的核心思想是將固定的大時間窗口拆分成多個小窗口,隨著時間的推移,這些小窗口不斷地滑動,統(tǒng)計也在持續(xù)變化。比如說,我們把 1 秒的大窗口拆分成 10 個 100 毫秒的小窗口,每個小窗口都有自己獨立的計數(shù)器。當請求到達時,我們不僅要統(tǒng)計當前小窗口內的請求數(shù),還要統(tǒng)計當前窗口及之前若干個小窗口的請求總數(shù),以此來判斷是否超過限流閾值。隨著時間每過 100 毫秒,窗口就向右滑動一格,最老的那個小窗口的計數(shù)就會被丟棄,同時納入最新的小窗口的計數(shù)。

這樣做的好處是顯而易見的,它使得流量統(tǒng)計更加平滑,能夠有效減少請求的突發(fā)性,避免在窗口切換時出現(xiàn)流量突增的情況。但由于它需要維護多個小窗口的計數(shù)器,并且在每次請求時都要進行更復雜的統(tǒng)計計算,所以實現(xiàn)起來相對復雜一些,對系統(tǒng)資源的消耗也會多一些 。不過,為了系統(tǒng)的穩(wěn)定性,這些代價通常是值得的,在對限流精度要求較高的場景中,滑動窗口計數(shù)器算法被廣泛應用。

漏桶算法

漏桶算法的原理就像我們日常生活中的漏斗一樣。請求就像水一樣,可以任意速率流入到一個桶中,而桶則以固定的速率將請求 “漏出” 進行處理。如果請求流入的速度太快,導致桶被裝滿了,那么多余的請求就會像溢出的水一樣被直接丟棄或者排隊等待處理。比如說,一個漏桶的容量設定為 100 個請求,漏出的速率是每秒 10 個請求。當請求以每秒 20 個的速度涌入時,桶會在 5 秒后被裝滿,之后新來的請求就會被拒絕。只有當桶中的請求被不斷處理,有了空閑空間后,新的請求才有可能進入桶中等待處理。

漏桶算法的最大優(yōu)點就是能夠非常平滑地處理流量,無論外界的請求流量如何波動,它都能保證請求以固定的速率被處理,就像漏斗里的水總是以穩(wěn)定的速度流出一樣,這對于保護下游系統(tǒng)免受突發(fā)流量的沖擊非常有效。但它也有明顯的缺點,那就是無法應對短暫的突發(fā)流量。即使系統(tǒng)在某個時刻非??臻e,請求也只能按照固定的速率慢慢排隊處理,這在一些對響應時間要求較高的場景,比如秒殺活動中,可能會導致用戶體驗很差,因為用戶的請求可能需要長時間等待才能被處理。

令牌桶算法

令牌桶算法是目前互聯(lián)網(wǎng)中應用最為廣泛的限流算法,它巧妙地在 “限制流量” 和 “允許突發(fā)” 之間找到了平衡。在這個算法中,系統(tǒng)會以一個恒定的速率往桶里生成令牌,每個令牌都可以看作是一個允許請求通過的 “許可證”。桶有一個固定的容量,當令牌生成的數(shù)量達到桶的容量時,新生成的令牌就會被丟棄。當請求到達時,它必須先從桶中獲取一個令牌,如果桶中有足夠的令牌,請求就可以立即被處理;如果桶中沒有令牌了,請求就會被拒絕或者等待,直到有新的令牌生成。

假設我們設定令牌桶的容量為 100 個令牌,生成令牌的速率是每秒 10 個。如果在前 5 秒內沒有請求到來,那么桶中就會積攢 50 個令牌。這時突然來了 80 個請求,由于桶中有足夠的令牌,這 80 個請求都可以立即被處理,充分體現(xiàn)了它允許突發(fā)流量的特性。同時,從長期來看,因為令牌的生成速率是固定的,所以它又能很好地限制平均流量,防止系統(tǒng)被持續(xù)的高流量壓垮。與漏桶算法相比,令牌桶算法更加靈活,它允許系統(tǒng)在有令牌儲備的情況下,快速處理突發(fā)的大量請求,避免了像漏桶算法那樣即使系統(tǒng)空閑也只能慢慢處理請求的尷尬,非常適合大多數(shù)需要限制流量同時又要應對突發(fā)情況的業(yè)務場景,比如 API 網(wǎng)關、電商平臺的搶購接口等。

在實際應用中,Google 的 Guava 工具包為我們提供了成熟的令牌桶算法實現(xiàn)。通過使用 Guava 的 RateLimiter 類,我們可以輕松地創(chuàng)建一個令牌桶實例,并設置每秒生成的令牌數(shù)。例如,RateLimiter limiter = RateLimiter.create(10.0) 表示創(chuàng)建一個每秒生成 10 個令牌的令牌桶。在處理請求時,我們可以使用 limiter.acquire() 方法來嘗試獲取令牌,如果獲取成功則表示請求可以繼續(xù)處理,否則請求可能需要等待或者被拒絕,這種簡單易用的方式大大提高了我們在項目中實現(xiàn)限流功能的效率 。

三、Spring Boot 實現(xiàn)網(wǎng)絡限速全攻略

(一)核心思路大揭秘

在 Spring Boot 項目中實現(xiàn)網(wǎng)絡限速,我們可以借助 Spring AOP(面向切面編程)的強大能力,結合令牌桶算法來達成目標。這就好比在一條高速公路上設置了多個收費站(AOP 切面),每個收費站都可以對過往的車輛(請求)進行檢查,看它們是否有足夠的 “通行證”(令牌),以此來控制車輛的通行速度(請求頻率)。

具體來說,我們會自定義一個注解,比如@RateLimit ,它就像是一個特殊的標識,被添加到需要限速的接口方法上。當請求到達這些被標記的接口時,Spring AOP 就會像一個敏銳的觀察者,立即捕獲到這個請求,并觸發(fā)我們預先定義好的限速邏輯。而這個限速邏輯的核心,就是基于令牌桶算法實現(xiàn)的。

令牌桶算法就像是一個神奇的桶,系統(tǒng)會以一個固定的速率往桶里放入令牌,每個令牌代表著一次請求的許可。當請求到來時,它必須從桶中獲取一個令牌才能繼續(xù)前進。如果桶里沒有令牌了,請求就會被拒絕或者等待,直到有新的令牌被生成。通過這種方式,我們可以有效地控制接口在單位時間內能夠處理的請求數(shù)量,從而實現(xiàn)網(wǎng)絡限速的目的。

(二)實現(xiàn)步驟詳細拆解

接下來,我將詳細介紹基于 Spring Boot + AOP 思想,使用令牌桶算法結合自定義注解實現(xiàn)網(wǎng)絡限速的具體步驟,每一步都配有相應的代碼示例,方便大家理解和實踐。

引入核心依賴 首先,在你的 Spring Boot 項目的pom.xml文件中,引入以下核心依賴:

<dependencies>
    <!-- Spring Boot Web核心依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- AOP依賴,用于攔截注解 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <!-- Lombok依賴,簡化代碼,如自動生成getter、setter、構造函數(shù)等 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

Spring Boot Web 依賴提供了構建 Web 應用所需的基本組件,讓我們能夠輕松創(chuàng)建和管理 HTTP 接口。AOP 依賴則是實現(xiàn)注解攔截的關鍵,它允許我們在不修改原有業(yè)務代碼的基礎上,在方法執(zhí)行前后、異常處理等階段插入自定義邏輯。Lombok 依賴可以大大簡化我們的代碼編寫工作,減少樣板代碼的冗余,提高開發(fā)效率。

自定義限速注解 在項目中創(chuàng)建一個新的注解類,用于標記需要限速的接口方法。例如,我們創(chuàng)建一個@RateLimit注解:

package com.example.ratelimit.annotation;

import java.lang.annotation.*;

/**
 * 網(wǎng)絡限速注解,添加在接口方法上即可實現(xiàn)限速
 */
@Target({ElementType.METHOD}) // 僅作用于方法
@Retention(RetentionPolicy.RUNTIME) // 運行時生效,允許AOP反射獲取注解信息
@Documented // 生成JavaDoc時包含該注解
public @interface RateLimit {
    /**
     * 每秒允許的請求數(shù)(限速閾值),默認10
     */
    double permitsPerSecond() default 10.0;

    /**
     * 限流后的提示信息,默認“請求過于頻繁,請稍后再試!”
     */
    String message() default "請求過于頻繁,請稍后再試!";

    /**
     * 限速唯一標識(可選),默認取請求接口的路徑(如/api/test),支持SpEL表達式,
     * 示例:#request.ip 按IP限速,#user.id 按用戶ID限速
     */
    String key() default "";
}

這個注解包含了三個主要參數(shù):permitsPerSecond用于設置每秒允許的請求數(shù),也就是限速閾值,默認值為 10;message用于設置當請求被限流時返回給客戶端的提示信息,默認是 “請求過于頻繁,請稍后再試!” ;key是一個可選參數(shù),用于指定限速的唯一標識,默認情況下會取請求接口的路徑。通過 SpEL 表達式,我們可以實現(xiàn)更加靈活的限速策略,比如按 IP 地址、用戶 ID 等進行限速。

實現(xiàn)令牌桶算法 創(chuàng)建一個線程安全的令牌桶工具類,用于管理令牌的生成和獲取。下面是一個簡單的實現(xiàn)示例:

package com.example.ratelimit.util;

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 令牌桶工具類(線程安全,支持多標識獨立限速)
 */
@Slf4j
public class TokenBucketUtil {

    /**
     * 存儲不同標識對應的令牌桶(key:限速標識,value:令牌桶)
     */
    private static final ConcurrentHashMap<String, TokenBucket> TOKEN_BUCKET_MAP = new ConcurrentHashMap<>();

    /**
     * 獲取令牌(非阻塞,獲取不到直接返回false)
     * @param key 限速標識
     * @param permitsPerSecond 每秒允許的請求數(shù)(令牌生成速率)
     * @return true:獲取令牌成功,false:限流
     */
    public static boolean tryAcquire(String key, double permitsPerSecond) {
        TokenBucket tokenBucket = TOKEN_BUCKET_MAP.computeIfAbsent(key, k -> new TokenBucket(permitsPerSecond));
        return tokenBucket.tryAcquire();
    }

    /**
     * 令牌桶內部類
     */
    private static class TokenBucket {
        // 令牌桶的容量,這里設置為100,可根據(jù)實際情況調整
        private static final int CAPACITY = 100;
        // 每秒生成的令牌數(shù)
        private final double rate;
        // 當前可用的令牌數(shù),使用AtomicLong保證線程安全
        private final AtomicLong tokens = new AtomicLong(CAPACITY);
        // 上次更新令牌的時間戳
        private long lastRefillTime = System.nanoTime();

        public TokenBucket(double rate) {
            this.rate = rate;
        }

        public boolean tryAcquire() {
            refill();
            return tokens.decrementAndGet() >= 0;
        }

        private void refill() {
            long now = System.nanoTime();
            // 計算距離上次更新令牌的時間間隔,單位為秒
            double elapsedTime = (now - lastRefillTime) / 1e9;
            // 根據(jù)時間間隔和生成速率,計算新生成的令牌數(shù)
            double newTokens = elapsedTime * rate;
            // 更新當前可用的令牌數(shù),確保不超過桶的容量
            tokens.addAndGet((long) Math.min(CAPACITY - tokens.get(), newTokens));
            // 更新上次更新令牌的時間戳
            lastRefillTime = now;
        }
    }
}

在這個工具類中,我們使用了一個ConcurrentHashMap來存儲不同標識對應的令牌桶,這樣可以支持多個接口或不同條件下的獨立限速。TokenBucket內部類負責具體的令牌管理邏輯,包括令牌的生成(refill方法)和獲?。?code>tryAcquire方法)。refill方法會根據(jù)當前時間和上次更新時間的差值,計算出這段時間內應該生成的令牌數(shù)量,并更新當前可用的令牌數(shù)。tryAcquire方法則會先調用refill方法補充令牌,然后嘗試獲取一個令牌,如果獲取成功則返回true,否則返回false,表示請求被限流。

AOP 攔截實現(xiàn)限速 創(chuàng)建一個 AOP 切面類,用于攔截添加了@RateLimit注解的接口方法,并進行限速判斷。示例代碼如下:

package com.example.ratelimit.aspect;

import com.example.ratelimit.annotation.RateLimit;
import com.example.ratelimit.util.TokenBucketUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class RateLimitAspect {

    @Around("@annotation(rateLimit)")
    public Object checkRateLimit(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
        // 獲取當前請求對象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 獲取限速標識,如果未設置,則使用請求接口路徑
        String key = rateLimit.key().isEmpty()? request.getRequestURI() : rateLimit.key();

        // 從令牌桶中獲取令牌,判斷是否超過限速
        if (!TokenBucketUtil.tryAcquire(key, rateLimit.permitsPerSecond())) {
            log.warn("請求被限流,接口: {}, 提示信息: {}", request.getRequestURI(), rateLimit.message());
            return rateLimit.message();
        }

        // 如果獲取令牌成功,繼續(xù)執(zhí)行接口方法
        return joinPoint.proceed();
    }
}

在這個切面類中,我們使用@Around注解定義了一個環(huán)繞通知,它會攔截所有添加了@RateLimit注解的方法。在通知方法中,首先獲取當前的 HTTP 請求對象,然后根據(jù)注解中設置的key值或請求接口路徑,作為限速標識從令牌桶工具類中嘗試獲取令牌。如果獲取令牌失敗,說明請求超過了限速閾值,記錄一條警告日志,并返回預先設置的限流提示信息給客戶端;如果獲取令牌成功,則調用joinPoint.proceed()方法,繼續(xù)執(zhí)行被攔截的接口方法,讓請求正常通過。

四、配置說明與參數(shù)調整

在使用@RateLimit注解進行網(wǎng)絡限速時,合理配置注解中的參數(shù)以及調整令牌桶的相關參數(shù)至關重要,這直接關系到限速策略是否能夠精準地滿足業(yè)務需求。

注解參數(shù)配置

  • permitsPerSecond(限速閾值):這個參數(shù)設置了每秒允許通過的請求數(shù)量,它是限速的核心指標。在實際應用中,需要根據(jù)接口的業(yè)務特性和服務器的承載能力來精確設定。比如,對于一個簡單的查詢接口,假設服務器每秒能夠輕松處理 100 次請求,且該接口的使用頻率相對穩(wěn)定,沒有明顯的突發(fā)流量,那么可以將permitsPerSecond設置為 100 。但如果是一個涉及復雜業(yè)務邏輯和數(shù)據(jù)庫操作的接口,或者服務器資源有限,可能就需要將這個值設置得低一些,比如 20 - 50,以防止過多請求導致服務器負載過高。
  • message(限流提示信息):當請求被限流時,這個參數(shù)定義了返回給客戶端的提示信息。清晰、友好的提示信息能夠幫助用戶理解為什么請求失敗,并引導他們采取正確的操作。例如,“您的請求過于頻繁,請稍后再試。給您帶來不便,敬請諒解!” 這樣的信息既明確告知用戶請求被限流,又表達了對用戶的歉意,有助于提升用戶體驗。在國際化的項目中,還可以考慮根據(jù)不同的語言環(huán)境返回不同的提示信息,以滿足全球用戶的需求。
  • key(限速唯一標識):此參數(shù)用于指定限速的唯一標識,默認情況下會使用請求接口的路徑。通過使用 SpEL 表達式,我們可以實現(xiàn)更加靈活的限速策略。如果想要按 IP 地址對請求進行限速,可以將key設置為#request.remoteAddr 。這樣,來自不同 IP 的請求就會被獨立統(tǒng)計和限速,防止某個惡意 IP 通過大量請求耗盡服務器資源。如果是一個多用戶的系統(tǒng),希望按用戶 ID 進行限速,以保證每個用戶的公平訪問,可以將key設置為#user.id ,其中#user是 Spring 上下文里的用戶對象。在一些復雜的業(yè)務場景中,還可以結合多個因素來生成唯一標識,比如#request.remoteAddr + '_' + #user.id ,實現(xiàn)按 IP 和用戶 ID 雙重維度的限速。

令牌桶參數(shù)調整

  • 桶容量(capacity):在我們之前實現(xiàn)的令牌桶工具類中,桶容量被硬編碼為 100 ,但在實際應用中,這是一個需要根據(jù)業(yè)務場景靈活調整的重要參數(shù)。桶容量決定了系統(tǒng)能夠承受的突發(fā)流量大小。如果一個電商平臺舉辦限時秒殺活動,在活動開始的瞬間,可能會有大量用戶同時發(fā)起請求,這時就需要一個較大的桶容量來應對突發(fā)流量。假設我們預計活動開始時每秒的請求峰值可能達到 500,為了保證在短時間內大部分請求能夠被正常處理,就可以將桶容量設置為 500 或更高。相反,如果是一個對穩(wěn)定性要求極高,不希望出現(xiàn)任何突發(fā)流量沖擊的系統(tǒng),比如銀行的核心交易系統(tǒng),桶容量就可以設置得相對較小,以確保流量始終保持平穩(wěn)。
  • 令牌生成速率(rate):這個參數(shù)與@RateLimit注解中的permitsPerSecond相對應,它決定了令牌桶中令牌的生成速度,也就是系統(tǒng)允許的平均請求處理速率。如果一個視頻直播平臺,為了保證所有用戶都能流暢觀看直播,需要限制每個用戶對直播流接口的請求頻率,防止個別用戶占用過多帶寬。假設平臺規(guī)定每個用戶每秒最多只能請求直播流數(shù)據(jù) 5 次,那么令牌生成速率就可以設置為 5 。在實際調整時,還需要考慮系統(tǒng)的資源利用率和業(yè)務的實時性要求。如果將令牌生成速率設置得過低,雖然能夠有效限制流量,但可能會導致用戶請求處理不及時,影響用戶體驗;而設置得過高,則可能無法達到限流的目的,使系統(tǒng)面臨過載的風險。
  • 調整策略:在系統(tǒng)運行過程中,業(yè)務場景可能會發(fā)生變化,比如電商平臺在不同的促銷活動期間,用戶的訪問量和行為模式會有很大差異;或者隨著業(yè)務的增長,系統(tǒng)的負載能力也會發(fā)生變化。因此,需要建立一套 動態(tài)調整令牌桶參數(shù)的機制??梢酝ㄟ^監(jiān)控系統(tǒng)實時收集接口的請求數(shù)據(jù),包括請求頻率、響應時間、服務器資源利用率等指標。當發(fā)現(xiàn)接口的請求頻率持續(xù)超過設定的限速閾值,且服務器資源利用率過高時,說明當前的限速策略可能過于寬松,需要適當降低令牌生成速率或減小桶容量;反之,如果接口的請求頻率遠低于限速閾值,且服務器資源有大量空閑,就可以考慮提高令牌生成速率或增大桶容量,以充分利用系統(tǒng)資源,提升服務的吞吐量。還可以結合機器學習算法,根據(jù)歷史數(shù)據(jù)和實時監(jiān)控信息,自動預測業(yè)務流量的變化趨勢,從而更加智能地調整令牌桶參數(shù) 。

五、測試驗證與效果展示

為了驗證我們在 Spring Boot 中實現(xiàn)的網(wǎng)絡限速功能是否有效,接下來將使用 Postman 工具進行詳細的測試,并直觀地展示測試結果。

測試準備

啟動 Spring Boot 應用:確保按照前面步驟實現(xiàn)的 Spring Boot 項目已經成功啟動,監(jiān)聽的端口為默認的 8080(如果有修改,請根據(jù)實際情況調整)。

配置測試接口:在控制器類中,添加一個簡單的測試接口,并使用@RateLimit注解進行限速配置。例如:

import com.example.ratelimit.annotation.RateLimit;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @RateLimit(permitsPerSecond = 5, message = "請求過于頻繁,請稍后再試", key = "#request.remoteAddr")
    @GetMapping("/test")
    public String test() {
        return "測試接口,訪問成功";
    }
}

這里將/test接口的限速閾值設置為每秒 5 次,限流提示信息為 “請求過于頻繁,請稍后再試”,并按請求的 IP 地址進行限速,以確保不同 IP 的訪問相互獨立。

測試過程

正常請求測試:打開 Postman,發(fā)送 GET 請求到http://localhost:8080/test 。在短時間內連續(xù)發(fā)送 5 次請求,可以觀察到每次請求都能正常返回 “測試接口,訪問成功”,說明在限速閾值范圍內,請求能夠順利通過。

限速測試:緊接著,快速連續(xù)發(fā)送超過 5 次請求(例如發(fā)送 10 次)。從第 6 次請求開始,Postman 返回的響應內容為 “請求過于頻繁,請稍后再試”,這表明當請求頻率超過每秒 5 次的限速閾值時,限速功能生效,后續(xù)請求被成功攔截,并返回了預先設置的限流提示信息。

多 IP 測試(驗證按 IP 限速):使用不同的 IP 地址(可以通過修改本地代理或者在不同網(wǎng)絡環(huán)境下測試),分別對/test接口進行請求??梢园l(fā)現(xiàn),每個 IP 都有獨立的限速計數(shù),互不影響。例如,IP1 在短時間內發(fā)送超過 5 次請求后被限速,但 IP2 仍然可以正常發(fā)送請求,直到其自身的請求次數(shù)也超過限速閾值,進一步驗證了按 IP 地址限速的有效性。

測試結果展示

正常請求響應

{
    "響應狀態(tài)碼": 200,
    "響應內容": "測試接口,訪問成功"
}

限速響應

{
    "響應狀態(tài)碼": 200,
    "響應內容": "請求過于頻繁,請稍后再試"
}

通過以上測試過程和結果展示,可以清晰地看到我們基于 Spring Boot + AOP + 令牌桶算法實現(xiàn)的網(wǎng)絡限速功能運行正常,能夠準確地按照設定的限速策略對接口請求進行限制,有效保護系統(tǒng)免受過高流量的沖擊 ,確保了系統(tǒng)在高并發(fā)場景下的穩(wěn)定性和可靠性。在實際應用中,你可以根據(jù)業(yè)務需求,靈活調整限速注解的參數(shù),以適應不同接口和場景的限速要求。

六、總結與拓展

在今天的分享中,我們深入探討了 Spring Boot 中實現(xiàn)網(wǎng)絡限速的重要性、常見策略以及基于 AOP 和令牌桶算法的具體實現(xiàn)方案。通過合理配置注解參數(shù)和調整令牌桶參數(shù),我們能夠精準地控制接口的訪問頻率,有效抵御惡意攻擊、應對流量峰值并保護核心資源。測試結果也充分驗證了該方案的有效性和可靠性。

在未來的拓展方向上,我們可以進一步優(yōu)化令牌桶算法的實現(xiàn),提高其性能和效率。可以考慮引入分布式緩存(如 Redis)來存儲令牌桶的狀態(tài),實現(xiàn)分布式環(huán)境下的統(tǒng)一限速管理,以適應微服務架構和大規(guī)模集群的需求。還可以結合實時監(jiān)控和動態(tài)調整機制,根據(jù)系統(tǒng)的實時負載和業(yè)務需求,自動調整限速策略,使系統(tǒng)能夠更加智能、靈活地應對各種復雜的網(wǎng)絡情況。

以上就是基于SpringBoot實現(xiàn)網(wǎng)絡限速功能的詳細內容,更多關于SpringBoot限速的資料請關注腳本之家其它相關文章!

相關文章

  • Spring Cloud Nacos 和 Eureka區(qū)別解析

    Spring Cloud Nacos 和 Eureka區(qū)別解析

    Spring Cloud Nacos 和 Spring Cloud Eureka 都是 Spring Cloud 微服務框架中的服務注冊和發(fā)現(xiàn)組件,用于幫助開發(fā)者輕松地構建和管理微服務應用,這篇文章主要介紹了Spring Cloud Nacos 和 Eureka區(qū)別,需要的朋友可以參考下
    2023-08-08
  • Java數(shù)組使用binarySearch()方法查找指定元素的實現(xiàn)

    Java數(shù)組使用binarySearch()方法查找指定元素的實現(xiàn)

    這篇文章主要介紹了Java數(shù)組使用binarySearch()方法查找指定元素的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • SpringBoot中事務失效的六個原因解析

    SpringBoot中事務失效的六個原因解析

    這篇文章主要介紹了SpringBoot中事務失效的六個原因解析,由于Spring的事務是基于AOP的方式結合動態(tài)代理來實現(xiàn)的,因此事務方法一定要是public的,這樣才能便于被Spring做事務的代理和增強,需要的朋友可以參考下
    2023-10-10
  • java使用EditText控件時不自動彈出輸入法的方法

    java使用EditText控件時不自動彈出輸入法的方法

    這篇文章主要介紹了java使用EditText控件時不自動彈出輸入法的方法,需要的朋友可以參考下
    2015-03-03
  • Spring Cloud中關于Feign的常見問題總結

    Spring Cloud中關于Feign的常見問題總結

    這篇文章主要給大家介紹了Spring Cloud中關于Feign的常見問題,文中通過示例代碼介紹的很詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 手把手帶你用java搞定青蛙跳臺階

    手把手帶你用java搞定青蛙跳臺階

    這篇文章主要給大家介紹了關于Java青蛙跳臺階問題的解決思路與代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • SpringBoot集成Druid監(jiān)控頁面最小化配置操作

    SpringBoot集成Druid監(jiān)控頁面最小化配置操作

    這篇文章主要介紹了SpringBoot集成Druid監(jiān)控頁面最小化配置操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • SpringMVC中Json數(shù)據(jù)格式轉換

    SpringMVC中Json數(shù)據(jù)格式轉換

    本文主要介紹了SpringMVC中Json數(shù)據(jù)格式轉換的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • 詳解spring封裝hbase的代碼實現(xiàn)

    詳解spring封裝hbase的代碼實現(xiàn)

    本篇文章主要介紹了詳解spring封裝hbase的代碼實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • springboot向elk寫日志實現(xiàn)過程

    springboot向elk寫日志實現(xiàn)過程

    這篇文章主要介紹了springboot向elk寫日志實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10

最新評論

普洱| 那曲县| 类乌齐县| 彭州市| 新昌县| 庐江县| 芦溪县| 浠水县| 商都县| 平度市| 黄平县| 金溪县| 佛教| 商城县| 宜君县| 弋阳县| 平果县| 贺州市| 万源市| 康定县| 临颍县| 中牟县| 漠河县| 双城市| 通道| 江津市| 仁怀市| 永兴县| 益阳市| 白城市| 隆德县| 广饶县| 香河县| 嘉禾县| 苏州市| 渭南市| 克什克腾旗| 大荔县| 沛县| 商城县| 奉节县|