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

java單機(jī)接口限流處理方案詳解

 更新時(shí)間:2021年11月25日 09:02:01   作者:景川呀  
這篇文章主要為大家詳細(xì)介紹了java單機(jī)接口限流處理方案,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

對(duì)單機(jī)服務(wù)做接口限流的處理方案

簡(jiǎn)單說(shuō)就是設(shè)定某個(gè)接口一定時(shí)間只接受固定次數(shù)的請(qǐng)求,比如/add接口1秒最多接收100次請(qǐng)求,多的直接拒絕,這個(gè)問(wèn)題很常見(jiàn),場(chǎng)景也好理解,直接上代碼:

/**
 * 單機(jī)限流
 */
@Slf4j
public class FlowLimit {

 //接口限流上限值和限流時(shí)間緩存
    private static Cache<String, AtomicLong> localCache = CacheBuilder.newBuilder().maximumSize(100)
            .expireAfterWrite(1000, TimeUnit.MILLISECONDS).build();

 //每個(gè)接口的上限緩存
    private static Map<String, Long> maxFlowLimitMap = new ConcurrentHashMap<>();

    private static final FlowLimit instance = new FlowLimit();

 //這塊的目的是初始化每個(gè)接口的上限,下面的變量:apiFlowLimitConfigure 
 //實(shí)際使用的時(shí)候應(yīng)該是從db或者其他地方獲取設(shè)置的每個(gè)接口的限流上限值,
 //這樣可以動(dòng)態(tài)的調(diào)整接口上限,比如直接修改db,不用發(fā)布,就可以調(diào)整接口限流值
    static {
        new ScheduledThreadPoolExecutor(1, runnable -> {
            Thread thread = new Thread(runnable, "api-flowLimit-configure");
//            thread.setDaemon(true);
            return thread;
        }).scheduleAtFixedRate(() -> {
            try {
                String apiFlowLimitConfigure = "{\"doAdd\":100}";  //表示/doAdd接口1秒接受100次請(qǐng)求
                Map mapObj = JSONObject.parseObject(apiFlowLimitConfigure, Map.class);
                if(mapObj != null){
                    mapObj.forEach((key, value) -> {
                        if(value != null){
                            instance.setMaxFlowLimit(key.toString(), new Long(value.toString()));
                        }else{
                            log.warn(key + " - 設(shè)置接口限流發(fā)現(xiàn)限流值為空,設(shè)置默認(rèn)值");
                            instance.setMaxFlowLimit(key.toString(), 100L);
                        }
                    });
                }
            } catch (Exception e) {
                log.error("設(shè)置接口限流出現(xiàn)異常{}", e);
            }
        }, 0, 3, TimeUnit.SECONDS);
    }

    public static FlowLimit getInstance() {
        return instance;
    }

    private FlowLimit setMaxFlowLimit(String key, Long maxFlowLimit) {
        maxFlowLimitMap.put(key, maxFlowLimit);
        return this;
    }

    public Boolean isAvailable(String key) {
        return checkAvailable(key, 1L);
    }

    public Boolean isAvailable(String key, Long incrNum) {
        return checkAvailable(key, incrNum);
    }

    private Boolean checkAvailable(String key, Long incrNum){
        Long maxFlowLimit = maxFlowLimitMap.get(key);
        if (null == maxFlowLimit || maxFlowLimit == 0) {
            return true;
        }
        if (incrAndGet(key, incrNum) <= maxFlowLimit.longValue()) {
            return true;
        } else {
            return false;
        }
    }

    private long incrAndGet(String key, final long n) {
        try {
            return localCache.get(key, new Callable<AtomicLong>() {
                @Override
                public AtomicLong call() throws Exception {
                    return new AtomicLong(0);
                }
            }).addAndGet(n);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return 0;
    }

    public long get(String key) {
        return incrAndGet(key, 0);
    }

}

上面這個(gè)就是單機(jī)限流邏輯,代碼不難,感覺(jué)沒(méi)必要使用ConcurrentHashMap,不過(guò)感覺(jué)無(wú)所謂了
這段代碼只需要加在需要限流的接口前面:

@GetMapping("doAdd")
public Boolean doAdd(){
    FlowLimit instance = FlowLimit.getInstance(); //單例獲取
    //查看當(dāng)前的/doAdd接口是否觸發(fā)了限流
    Boolean flowLimitFlag = instance.isAvailable("doAdd");
    if(!flowLimitFlag){
        log.warn("觸發(fā)限流,拒絕請(qǐng)求");
        return false;
    }
    //doAdd()
    return true;
}

調(diào)用實(shí)例如上

上面這個(gè)限流其實(shí)是有一定問(wèn)題的:比如你限定10秒鐘1000次,在第9.9秒的時(shí)候,突然進(jìn)來(lái)1000個(gè)請(qǐng)求,然后第10.1秒的時(shí)候,攻擊者,又進(jìn)來(lái)1000次請(qǐng)求,這樣,0.2秒之內(nèi),進(jìn)來(lái)2000次請(qǐng)求。。。
所以這個(gè)時(shí)候就需要令牌桶或者其他算法了,其他算法后面再寫(xiě)

沒(méi)怎么仔細(xì)測(cè)試,有問(wèn)題歡迎提出,共同學(xué)習(xí)

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何實(shí)現(xiàn)Java中一個(gè)簡(jiǎn)單的LinkedList

    如何實(shí)現(xiàn)Java中一個(gè)簡(jiǎn)單的LinkedList

    LinkedList與ArrayList都是List接口的具體實(shí)現(xiàn)類(lèi)。下面將介紹如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的LinkedList,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • Java List的remove()方法踩坑

    Java List的remove()方法踩坑

    Java的List在刪除元素時(shí),一般會(huì)用list.remove(o)/remove(i)方法。在使用時(shí),容易觸碰陷阱,本文就來(lái)介紹一下容易踩的坑,感興趣的可以了解一下
    2021-10-10
  • 詳解利用Spring加載Properties配置文件

    詳解利用Spring加載Properties配置文件

    本篇文章主要介紹了詳解利用Spring加載Properties配置文件,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • java實(shí)現(xiàn)點(diǎn)贊功能

    java實(shí)現(xiàn)點(diǎn)贊功能

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)點(diǎn)贊功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • java 解決異常 2 字節(jié)的 UTF-8 序列的字節(jié)2 無(wú)效的問(wèn)題

    java 解決異常 2 字節(jié)的 UTF-8 序列的字節(jié)2 無(wú)效的問(wèn)題

    這篇文章主要介紹了java 解決異常 2 字節(jié)的 UTF-8 序列的字節(jié) 2 無(wú)效的問(wèn)題的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • SpringCloud使用Nacos保存和讀取變量的配置方法

    SpringCloud使用Nacos保存和讀取變量的配置方法

    在使用SpringCloud開(kāi)發(fā)微服務(wù)時(shí),經(jīng)常會(huì)遇到一些比較小的后臺(tái)參數(shù)配置,這些配置不足以單獨(dú)開(kāi)一張表去存儲(chǔ),而且其他服務(wù)會(huì)讀取該參數(shù),這篇文章主要介紹了SpringCloud使用Nacos保存和讀取變量,需要的朋友可以參考下
    2022-07-07
  • Java this super代碼實(shí)例及使用方法總結(jié)

    Java this super代碼實(shí)例及使用方法總結(jié)

    這篇文章主要介紹了Java this super代碼實(shí)例及使用方法總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java中的三元運(yùn)算(三目運(yùn)算)以后用得到!

    Java中的三元運(yùn)算(三目運(yùn)算)以后用得到!

    Java提供了一個(gè)三元運(yùn)算符,可以同時(shí)操作3個(gè)表達(dá)式,下面這篇文章主要給大家介紹了關(guān)于Java中三元運(yùn)算(三目運(yùn)算)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • 一篇文章讓你三分鐘學(xué)會(huì)Java枚舉

    一篇文章讓你三分鐘學(xué)會(huì)Java枚舉

    這篇文章主要給大家介紹了如何通過(guò)三分鐘學(xué)會(huì)Java枚舉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • SpringBoot RESTful風(fēng)格入門(mén)講解

    SpringBoot RESTful風(fēng)格入門(mén)講解

    RESTful是一種web軟件風(fēng)格,它不是標(biāo)準(zhǔn)也不是協(xié)議,它不一定要采用,只是一種風(fēng)格,它倡導(dǎo)的是一個(gè)資源定位(url)及資源操作的風(fēng)格,這篇文章主要介紹了SpringBoot使用RESTful接口
    2022-11-11

最新評(píng)論

镇康县| 瑞金市| 湘阴县| 和林格尔县| 广汉市| 淮阳县| 连南| 长子县| 广昌县| 中江县| 东乡县| 长垣县| 新津县| 平乐县| 昌都县| 达孜县| 璧山县| 孝昌县| 炎陵县| 富裕县| 慈溪市| 中阳县| 布尔津县| 金湖县| 临城县| 泰兴市| 天祝| 黄大仙区| 文安县| 白城市| 墨脱县| 高安市| 高雄市| 嘉祥县| 宜兰市| 孝感市| 唐山市| 阳江市| 诏安县| 屯门区| 长海县|