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

Spring Boot接口限流的常用算法及特點(diǎn)

 更新時(shí)間:2021年02月05日 11:59:17   作者:俠夢(mèng)的開(kāi)發(fā)筆記  
這篇文章主要給大家介紹了關(guān)于Spring Boot接口限流的常用算法及特點(diǎn)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

在一個(gè)高并發(fā)系統(tǒng)中對(duì)流量的把控是非常重要的,當(dāng)巨大的流量直接請(qǐng)求到我們的服務(wù)器上沒(méi)多久就可能造成接口不可用,不處理的話甚至?xí)斐烧麄€(gè)應(yīng)用不可用。

那么何為限流呢?顧名思義,限流就是限制流量,就像你寬帶包了1個(gè)G的流量,用完了就沒(méi)了。通過(guò)限流,我們可以很好地控制系統(tǒng)的qps,從而達(dá)到保護(hù)系統(tǒng)的目的。本篇文章將會(huì)介紹一下常用的限流算法以及他們各自的特點(diǎn)。

算法介紹

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

計(jì)數(shù)器法是限流算法里最簡(jiǎn)單也是最容易實(shí)現(xiàn)的一種算法。比如我們規(guī)定,對(duì)于A接口來(lái)說(shuō),我們1分鐘的訪問(wèn)次數(shù)不能超過(guò)100個(gè)。那么我們可以這么做:在一開(kāi)始的時(shí)候,我們可以設(shè)置一個(gè)計(jì)數(shù)器counter,每當(dāng)一個(gè)請(qǐng)求過(guò)來(lái)的時(shí)候,counter就加1,如果counter的值大于100并且該請(qǐng)求與第一個(gè)請(qǐng)求的間隔時(shí)間還在1分鐘之內(nèi),那么說(shuō)明請(qǐng)求數(shù)過(guò)多;如果該請(qǐng)求與第一個(gè)請(qǐng)求的間隔時(shí)間大于1分鐘,且counter的值還在限流范圍內(nèi),那么就重置counter,具體算法的示意圖如下:

具體的偽代碼如下:

這個(gè)算法雖然簡(jiǎn)單,但是有一個(gè)十分致命的問(wèn)題,那就是臨界問(wèn)題,我們看下圖:

從上圖中我們可以看到,假設(shè)有一個(gè)惡意用戶,他在0:59時(shí),瞬間發(fā)送了100個(gè)請(qǐng)求,并且1:00又瞬間發(fā)送了100個(gè)請(qǐng)求,那么其實(shí)這個(gè)用戶在1秒里面,瞬間發(fā)送了200個(gè)請(qǐng)求。我們剛才規(guī)定的是1分鐘最多100個(gè)請(qǐng)求,也就是每秒鐘最多1.7個(gè)請(qǐng)求,用戶通過(guò)在時(shí)間窗口的重置節(jié)點(diǎn)處突發(fā)請(qǐng)求,可以瞬間超過(guò)我們的速率限制。用戶有可能通過(guò)算法的這個(gè)漏洞,瞬間壓垮我們的應(yīng)用。

聰明的朋友可能已經(jīng)看出來(lái)了,剛才的問(wèn)題其實(shí)是因?yàn)槲覀兘y(tǒng)計(jì)的精度太低。那么如何很好地處理這個(gè)問(wèn)題呢?或者說(shuō),如何將臨界問(wèn)題的影響降低呢?我們可以看下面的滑動(dòng)窗口算法。

滑動(dòng)窗口

滑動(dòng)窗口,又稱rolling window。為了解決這個(gè)問(wèn)題,我們引入了滑動(dòng)窗口算法。如果學(xué)過(guò)TCP網(wǎng)絡(luò)協(xié)議的話,那么一定對(duì)滑動(dòng)窗口這個(gè)名詞不會(huì)陌生。下面這張圖,很好地解釋了滑動(dòng)窗口算法:

在上圖中,整個(gè)紅色的矩形框表示一個(gè)時(shí)間窗口,在我們的例子中,一個(gè)時(shí)間窗口就是一分鐘。然后我們將時(shí)間窗口進(jìn)行劃分,比如圖中,我們就將滑動(dòng)窗口劃成了6格,所以每格代表的是10秒鐘。每過(guò)10秒鐘,我們的時(shí)間窗口就會(huì)往右滑動(dòng)一格。每一個(gè)格子都有自己獨(dú)立的計(jì)數(shù)器counter,比如當(dāng)一個(gè)請(qǐng)求在0:35秒的時(shí)候到達(dá),那么0:30~0:39對(duì)應(yīng)的counter就會(huì)加1。

那么滑動(dòng)窗口怎么解決剛才的臨界問(wèn)題的呢?我們可以看上圖,0:59到達(dá)的100個(gè)請(qǐng)求會(huì)落在灰色的格子中,而1:00到達(dá)的請(qǐng)求會(huì)落在橘黃色的格子中。當(dāng)時(shí)間到達(dá)1:00時(shí),我們的窗口會(huì)往右移動(dòng)一格,那么此時(shí)時(shí)間窗口內(nèi)的總請(qǐng)求數(shù)量一共是200個(gè),超過(guò)了限定的100個(gè),所以此時(shí)能夠檢測(cè)出來(lái)觸發(fā)了限流。

我再來(lái)回顧一下剛才的計(jì)數(shù)器算法,我們可以發(fā)現(xiàn),計(jì)數(shù)器算法其實(shí)就是滑動(dòng)窗口算法。只是它沒(méi)有對(duì)時(shí)間窗口做進(jìn)一步地劃分,為60s。

由此可見(jiàn),當(dāng)滑動(dòng)窗口的格子劃分的越多,那么滑動(dòng)窗口的滾動(dòng)就越平滑,限流的統(tǒng)計(jì)就會(huì)越精確。

漏桶算法

漏桶算法,又稱leaky bucket。為了理解漏桶算法,我們看一下對(duì)于該算法的示意圖:

從圖中我們可以看到,整個(gè)算法其實(shí)十分簡(jiǎn)單。首先,我們有一個(gè)固定容量的桶,有水流進(jìn)來(lái),也有水流出去。對(duì)于流進(jìn)來(lái)的水來(lái)說(shuō),我們無(wú)法預(yù)計(jì)一共有多少水會(huì)流進(jìn)來(lái),也無(wú)法預(yù)計(jì)水流的速度。但是對(duì)于流出去的水來(lái)說(shuō),這個(gè)桶可以固定水流出的速率。而且,當(dāng)桶滿了之后,多余的水將會(huì)溢出。

我們將算法中的水換成實(shí)際應(yīng)用中的請(qǐng)求,我們可以看到漏桶算法天生就限制了請(qǐng)求的速度。當(dāng)使用了漏桶算法,我們可以保證接口會(huì)以一個(gè)常速速率來(lái)處理請(qǐng)求。所以漏桶算法天生不會(huì)出現(xiàn)臨界問(wèn)題。具體的偽代碼實(shí)現(xiàn)如下:

令牌桶算法

令牌桶算法,又稱token bucket。為了理解該算法,我們?cè)賮?lái)看一下算法的示意圖:

從圖中我們可以看到,令牌桶算法比漏桶算法稍顯復(fù)雜。首先,我們有一個(gè)固定容量的桶,桶里存放著令牌(token)。桶一開(kāi)始是空的,token以一個(gè)固定的速率r往桶里填充,直到達(dá)到桶的容量,多余的令牌將會(huì)被丟棄。每當(dāng)一個(gè)請(qǐng)求過(guò)來(lái)時(shí),就會(huì)嘗試從桶里移除一個(gè)令牌,如果沒(méi)有令牌的話,請(qǐng)求無(wú)法通過(guò)。

具體的偽代碼實(shí)現(xiàn)如下:

RateLimiter實(shí)現(xiàn)

對(duì)于令牌桶的代碼實(shí)現(xiàn),可以直接使用Guava包中的RateLimiter。

相關(guān)變種

若仔細(xì)研究算法,我們會(huì)發(fā)現(xiàn)我們默認(rèn)從桶里移除令牌是不需要耗費(fèi)時(shí)間的。如果給移除令牌設(shè)置一個(gè)延時(shí)時(shí)間,那么實(shí)際上又采用了漏桶算法的思路。Google的guava庫(kù)下的SmoothWarmingUp類就采用了這個(gè)思路。

臨界問(wèn)題

我們?cè)賮?lái)考慮一下臨界問(wèn)題的場(chǎng)景。在0:59秒的時(shí)候,由于桶內(nèi)積滿了100個(gè)token,所以這100個(gè)請(qǐng)求可以瞬間通過(guò)。但是由于token是以較低的速率填充的,所以在1:00的時(shí)候,桶內(nèi)的token數(shù)量不可能達(dá)到100個(gè),那么此時(shí)不可能再有100個(gè)請(qǐng)求通過(guò)。所以令牌桶算法可以很好地解決臨界問(wèn)題。下圖比較了計(jì)數(shù)器(左)和令牌桶算法(右)在臨界點(diǎn)的速率變化。我們可以看到雖然令牌桶算法允許突發(fā)速率,但是下一個(gè)突發(fā)速率必須要等桶內(nèi)有足夠的token后才能發(fā)生:

總結(jié)

計(jì)數(shù)器 VS 滑動(dòng)窗口

計(jì)數(shù)器算法是最簡(jiǎn)單的算法,可以看成是滑動(dòng)窗口的低精度實(shí)現(xiàn)?;瑒?dòng)窗口由于需要存儲(chǔ)多份的計(jì)數(shù)器(每一個(gè)格子存一份),所以滑動(dòng)窗口在實(shí)現(xiàn)上需要更多的存儲(chǔ)空間。也就是說(shuō),如果滑動(dòng)窗口的精度越高,需要的存儲(chǔ)空間就越大。

漏桶算法 VS 令牌桶算法

漏桶算法和令牌桶算法最明顯的區(qū)別是令牌桶算法允許流量一定程度的突發(fā)。因?yàn)槟J(rèn)的令牌桶算法,取走token是不需要耗費(fèi)時(shí)間的,也就是說(shuō),假設(shè)桶內(nèi)有100個(gè)token時(shí),那么可以瞬間允許100個(gè)請(qǐng)求通過(guò)。

令牌桶算法由于實(shí)現(xiàn)簡(jiǎn)單,且允許某些流量的突發(fā),對(duì)用戶友好,所以被業(yè)界采用地較多。當(dāng)然我們需要具體情況具體分析,只有最合適的算法,沒(méi)有最優(yōu)的算法。

到此這篇關(guān)于Spring Boot接口限流的常用算法及特點(diǎn)的文章就介紹到這了,更多相關(guān)Spring Boot接口限流算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring基于注解管理bean實(shí)現(xiàn)方式講解

    Spring基于注解管理bean實(shí)現(xiàn)方式講解

    很多時(shí)候我們需要根據(jù)不同的條件在容器中加載不同的Bean,或者根據(jù)不同的條件來(lái)選擇是否在容器中加載某個(gè)Bean,這就是Bean的加載控制,一般我們可以通過(guò)編程式或注解式兩種不同的方式來(lái)完成Bean的管理
    2023-01-01
  • idea中使用git插件回滾代碼的流程步驟

    idea中使用git插件回滾代碼的流程步驟

    使用idea開(kāi)發(fā)java代碼時(shí),如果想回滾git提交的代碼, 需要操作三步,本篇步驟操作前,前提是你的電腦已經(jīng)安裝了git插件,并且你的idea也集成了git插件,下面是詳細(xì)步驟,需要的朋友可以參考下
    2025-04-04
  • SpringBoot下Mybatis的緩存的實(shí)現(xiàn)步驟

    SpringBoot下Mybatis的緩存的實(shí)現(xiàn)步驟

    這篇文章主要介紹了SpringBoot下Mybatis的緩存的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • SpringCloud?Ribbon負(fù)載均衡流程分析

    SpringCloud?Ribbon負(fù)載均衡流程分析

    在Eureka注冊(cè)中心中我們?cè)谔砑油闌LoadBalanced注解,即可實(shí)現(xiàn)負(fù)載均衡功能,現(xiàn)在一起探索一下負(fù)載均衡的原理(Ribbon),感興趣的朋友一起看看吧
    2024-03-03
  • java抓取網(wǎng)頁(yè)或文件中的郵箱號(hào)碼

    java抓取網(wǎng)頁(yè)或文件中的郵箱號(hào)碼

    這篇文章主要為大家詳細(xì)介紹了java如何抓取網(wǎng)頁(yè)或文件中的郵箱號(hào)碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Java使用sftp定時(shí)下載文件的示例代碼

    Java使用sftp定時(shí)下載文件的示例代碼

    SFTP 為 SSH的其中一部分,是一種傳輸檔案至 Blogger 伺服器的安全方式。接下來(lái)通過(guò)本文給大家介紹了Java使用sftp定時(shí)下載文件的示例代碼,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-05-05
  • SpringBoot中加密模塊的使用

    SpringBoot中加密模塊的使用

    本文主要介紹了SpringBoot中加密模塊的使用,包括對(duì)稱加密、非對(duì)稱加密和哈希加密等,同時(shí)還會(huì)提供相應(yīng)的代碼示例,感興趣的朋友可以參考一下
    2023-05-05
  • Java利用完全二叉樹(shù)創(chuàng)建大根堆和小根堆

    Java利用完全二叉樹(shù)創(chuàng)建大根堆和小根堆

    大根堆是每個(gè)結(jié)點(diǎn)的值不大于他的父親結(jié)點(diǎn)的值;小根堆是每個(gè)結(jié)點(diǎn)的值不小于他的父親結(jié)點(diǎn)的值。本文將利用完全二叉樹(shù)創(chuàng)建大根堆和小根堆,感興趣的可以了解一下
    2022-08-08
  • @ConfigurationProperties遇到的坑及解決

    @ConfigurationProperties遇到的坑及解決

    這篇文章主要介紹了解決@ConfigurationProperties遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java selenium處理極驗(yàn)滑動(dòng)驗(yàn)證碼示例

    Java selenium處理極驗(yàn)滑動(dòng)驗(yàn)證碼示例

    本篇文章主要介紹了Java selenium處理極驗(yàn)滑動(dòng)驗(yàn)證碼示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10

最新評(píng)論

连云港市| 元氏县| 阳谷县| 桃园市| 宝清县| 通榆县| 大英县| 汪清县| 通道| 吴堡县| 禄劝| 贵阳市| 阿坝县| 淳化县| 大荔县| 定陶县| 巫山县| 吴江市| 巍山| 神木县| 洞头县| 扬州市| 九江市| 景宁| 株洲市| 浮梁县| 酒泉市| 武宁县| 广南县| 岳西县| 卓尼县| 洛阳市| 东乌| 阜南县| 巴东县| 墨脱县| 闸北区| 汝城县| 台北市| 冀州市| 阿尔山市|