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

SpringBoot中間件封裝限流器的方案詳解

 更新時間:2023年07月10日 17:09:02   作者:看表該更新博客了  
這篇文章主要介紹了SpringBoot中間件封裝限流器,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

背景

通常能知道一個系統(tǒng)服務(wù)在正產(chǎn)增速下流量大小,擴容與壓測也是基于此。若有突發(fā)或者惡意攻擊訪問,都要將流量攔截在外。這部分功能不屬于業(yè)務(wù)側(cè),它是通用非業(yè)務(wù)的共性需求,所以我們將共性抽取為限流中間件。

方案設(shè)計

圖解:

Ratelimiter

  • 谷歌Guava庫中的一個限流工具類,用于限制訪問限制某一資源,令牌桶思想的一個實現(xiàn),可實現(xiàn)流量控制。

用到其兩個方法:

  • create():創(chuàng)建一個RateLimiter實例,并設(shè)置該實例的限流速率(即允許每秒執(zhí)行的任務(wù)數(shù)),例如:
RateLimiter rateLimiter = RateLimiter.create(10);

上述代碼將創(chuàng)建一個每秒允許10個任務(wù)的RateLimiter實例。

tryAcquire():嘗試獲取一個許可,若獲取成功則返回true,否則返回false。 例如:

if (rateLimiter.tryAcquire()) {
    // do something
}

上述代碼將嘗試獲取一個許可,如果該實例當(dāng)前擁有足夠的許可,則執(zhí)行do something操作

使用自定義注解和AOP,攔截需要被限流保護的方法。

攔截后,用Ratelimiter做限流處理

  • 使用自定義注解和AOP,攔截需要被限流保護的方法。
  • 攔截后,用Ratelimiter做限流處理

代碼示例

1.自定義注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoRateLimiter {
    // 每秒訪問次數(shù)限制
    public double rate() default 0d;
    // 超頻后的觸發(fā)熔斷默認(rèn)響應(yīng)結(jié)果
    public String returnJson() default "";
}

2.常量類

public class Constant {
    /**
     * 全局Hashmap,用于存放【方法】對應(yīng)的限流類
     * key: 類名 + 方法名
     * value: 對應(yīng)限流類
     */
    public static Map<String, RateLimiter> stringRateLimiterMap = Collections.synchronizedMap(new HashMap<String, RateLimiter>());
}

3.切面邏輯處理

PS:切面中的實現(xiàn)細(xì)節(jié)/注解的使用已經(jīng)在統(tǒng)一白名單中間件 文章中詳細(xì)梳理過了,需要請移步

@Component
@Aspect
public class RateLimiterHandle {
    // 切點
    @Pointcut("@annotation(com.example.ratelimiteer.annotation.DoRateLimiter)")
    public void aopPointcut() {
    }
    /**
     * @param jp            切點
     * @param doRateLimiter 注解實例
     * @return 方法響應(yīng)結(jié)果
     * @throws Throwable
     */
    @Around(value = "aopPointcut()&& @annotation(doRateLimiter)")
    public Object handle(ProceedingJoinPoint jp, DoRateLimiter doRateLimiter) throws Throwable {
        // 判斷是否開啟限流
        if (doRateLimiter.rate() == 0d) {
            return jp.proceed();
        }
        // 構(gòu)建限流哈希Map的Key: 類名 + "." + "方法名"
        String className = jp.getTarget().getClass().getName();
        MethodSignature signature = (MethodSignature) jp.getSignature();
        Method method = jp.getTarget().getClass().getMethod(signature.getMethod().getName(), signature.getMethod().getParameterTypes());
        String methodName = method.getName();
        String key = className + "." + methodName;
        // 第一次走到該接口
        if (!Constant.stringRateLimiterMap.containsKey(key)) {
            Map<String, RateLimiter> rateLimiterMap = Constant.stringRateLimiterMap;
            rateLimiterMap.put(key, RateLimiter.create(doRateLimiter.rate()));
        }
        // 判斷是否限流
        RateLimiter rateLimiter = Constant.stringRateLimiterMap.get(key);
        if (rateLimiter.tryAcquire()) {
            // 未超過訪問限制,則繼續(xù)執(zhí)行對應(yīng)業(yè)務(wù)邏輯
            return jp.proceed();
        } else {
            // 超過訪問限制,則返回默認(rèn)熔斷響應(yīng)結(jié)果(即注解中的returnJson)
            return JSON.parseObject(doRateLimiter.returnJson());
        }
    }
}

測試

controller如下,僅允許一個并發(fā)

壓測兩個并發(fā)

result:嘗試拿一個許可(RateLimiter.tryAcquire())未拿到(即超頻),返回注解中的returnJson()

到此這篇關(guān)于SpringBoot中間件封裝限流器的文章就介紹到這了,更多相關(guān)SpringBoot限流器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java讀寫鎖ReadWriteLock原理與應(yīng)用場景詳解

    Java讀寫鎖ReadWriteLock原理與應(yīng)用場景詳解

    這篇文章主要介紹了Java讀寫鎖ReadWriteLock原理與應(yīng)用場景詳解,讀寫狀態(tài)的設(shè)計,寫鎖的獲取與釋放,鎖降級需要的朋友可以參考下
    2023-02-02
  • http調(diào)用controller方法時openfeign執(zhí)行流程

    http調(diào)用controller方法時openfeign執(zhí)行流程

    這篇文章主要為大家介紹了http調(diào)用controller方法時openfeign執(zhí)行流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Java判斷對象是否為空(包括null ,

    Java判斷對象是否為空(包括null ,"")的方法

    這篇文章主要介紹了Java判斷對象是否為空(包括null ,"")的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • java字符串拼接與性能分析詳解

    java字符串拼接與性能分析詳解

    在JAVA中拼接兩個字符串的最簡便的方式就是使用操作符”+”。如果你用”+”來連接固定長度的字符串,可能性能上會稍受影響,但是如果你是在循環(huán)中來”+”多個串的話,性能將指數(shù)倍的下降,下面我們分析一下JAVA字符串拼接的性能
    2014-01-01
  • Java實現(xiàn)學(xué)生管理系統(tǒng)詳解流程

    Java實現(xiàn)學(xué)生管理系統(tǒng)詳解流程

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • springboot加載一個properties文件轉(zhuǎn)換為map方式

    springboot加載一個properties文件轉(zhuǎn)換為map方式

    這篇文章主要介紹了springboot加載一個properties文件轉(zhuǎn)換為map方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • mybatis-plus實現(xiàn)邏輯刪除的示例代碼

    mybatis-plus實現(xiàn)邏輯刪除的示例代碼

    本文主要介紹了mybatis-plus實現(xiàn)邏輯刪除的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • SpringBoot集成Redisson操作Redis的實現(xiàn)方法

    SpringBoot集成Redisson操作Redis的實現(xiàn)方法

    Redisson是一個用于Java的Redis客戶端,它提供了在分布式環(huán)境下操作Redis數(shù)據(jù)庫的簡單、高效的方式,本文主要介紹了SpringBoot集成Redisson操作Redis的實現(xiàn)方法,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Spring在代碼中獲取bean的方法小結(jié)

    Spring在代碼中獲取bean的方法小結(jié)

    在工作中有時候我們需要在非spring依賴注入或管理的類中獲取service、dao等bean對象,這時候用@Autowired和@Resource顯然是不行的,那么下面這篇文章就給大家了整理幾種獲取bean的方式,對大家的學(xué)習(xí)和工作具有一定的參考借鑒,下面來一起看看吧。
    2016-11-11
  • 簡單聊聊Java程序中的換行符

    簡單聊聊Java程序中的換行符

    Java程序中的換行符一般使用“\n”表示,它是一個轉(zhuǎn)義字符,表示換行符。根據(jù)操作系統(tǒng)的不同,換行符的實際表示可能不同,本文就來簡單聊聊他們的區(qū)別與使用吧
    2023-03-03

最新評論