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

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

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

背景

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

方案設(shè)計(jì)

圖解:

Ratelimiter

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

用到其兩個(gè)方法:

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

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

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

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

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

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

攔截后,用Ratelimiter做限流處理

  • 使用自定義注解和AOP,攔截需要被限流保護(hù)的方法。
  • 攔截后,用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,用于存放【方法】對(duì)應(yīng)的限流類
     * key: 類名 + 方法名
     * value: 對(duì)應(yīng)限流類
     */
    public static Map<String, RateLimiter> stringRateLimiterMap = Collections.synchronizedMap(new HashMap<String, RateLimiter>());
}

3.切面邏輯處理

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

@Component
@Aspect
public class RateLimiterHandle {
    // 切點(diǎn)
    @Pointcut("@annotation(com.example.ratelimiteer.annotation.DoRateLimiter)")
    public void aopPointcut() {
    }
    /**
     * @param jp            切點(diǎn)
     * @param doRateLimiter 注解實(shí)例
     * @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í)行對(duì)應(yīng)業(yè)務(wù)邏輯
            return jp.proceed();
        } else {
            // 超過訪問限制,則返回默認(rèn)熔斷響應(yīng)結(jié)果(即注解中的returnJson)
            return JSON.parseObject(doRateLimiter.returnJson());
        }
    }
}

測(cè)試

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

壓測(cè)兩個(gè)并發(fā)

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

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

相關(guān)文章

  • Java pdu短信解碼全面解析

    Java pdu短信解碼全面解析

    本文是根據(jù)python的方法改寫的pdu短信解碼,非常不錯(cuò),代碼簡(jiǎn)單易懂具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-10-10
  • Java工廠模式的深入了解

    Java工廠模式的深入了解

    這篇文章主要為大家介紹了Java工廠模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解

    Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解

    這篇文章主要介紹了Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解,Activemq服務(wù)端配置重新投遞次數(shù)超過?MaximumRedeliveries?,則會(huì)進(jìn)入死信隊(duì)列,默認(rèn)情況,有一個(gè)死信隊(duì)列:AcitveMQ.DLQ,所有的消息都投遞到此隊(duì)列,包括過期消息,重投遞失敗消息,需要的朋友可以參考下
    2023-12-12
  • Java NumberFormat格式化float類型的bug

    Java NumberFormat格式化float類型的bug

    今天小編就為大家分享一篇關(guān)于Java NumberFormat格式化float類型的bug,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • SpringBoot 如何編寫配置文件

    SpringBoot 如何編寫配置文件

    這篇文章主要介紹了SpringBoot 編寫配置文件的兩種方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • MyBatis批量插入的五種方式小結(jié)(MyBatis以集合方式批量新增)

    MyBatis批量插入的五種方式小結(jié)(MyBatis以集合方式批量新增)

    本文主要介紹了MyBatis批量插入的五種方式小結(jié)(MyBatis以集合方式批量新增),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 利用EasyExcel導(dǎo)出帶有選擇校驗(yàn)框的excel

    利用EasyExcel導(dǎo)出帶有選擇校驗(yàn)框的excel

    EasyExcel是一個(gè)輕量級(jí)的Excel處理工具,支持Excel?2003(xls)和Excel?2007及以上版本(xlsx)的文件格式,本文將利用EasyExcel導(dǎo)出帶有選擇校驗(yàn)框的excel,需要的可以參考下
    2024-12-12
  • 使用Spring Cloud Feign遠(yuǎn)程調(diào)用的方法示例

    使用Spring Cloud Feign遠(yuǎn)程調(diào)用的方法示例

    這篇文章主要介紹了使用Spring Cloud Feign遠(yuǎn)程調(diào)用的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • HelloSpringMVC配置版實(shí)現(xiàn)步驟解析

    HelloSpringMVC配置版實(shí)現(xiàn)步驟解析

    這篇文章主要介紹了HelloSpringMVC配置版實(shí)現(xiàn)步驟解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java While循環(huán) do-while循環(huán)用法

    Java While循環(huán) do-while循環(huán)用法

    循環(huán)語句就是讓計(jì)算機(jī)根據(jù)條件做循環(huán)計(jì)算,在條件滿足時(shí)繼續(xù)循環(huán),條件不滿足時(shí)退出循環(huán),需要的朋友可以參考下
    2020-11-11

最新評(píng)論

祁门县| 芷江| 东安县| 康马县| 吉水县| 孟村| 山阳县| 伽师县| 崇信县| 杭锦后旗| 仙桃市| 津市市| 宁国市| 巨野县| 商城县| 封丘县| 泰宁县| 磐安县| 芮城县| 旬阳县| 大新县| 二连浩特市| 甘洛县| 潜江市| 军事| 临泽县| 嘉定区| 从江县| 临泉县| 永平县| 安仁县| 平凉市| 兴和县| 随州市| 堆龙德庆县| 石屏县| 石台县| 仁化县| 习水县| 赣榆县| 双桥区|