日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

面試必備:四種經(jīng)典限流算法講解

來源: 責(zé)編: 時(shí)間:2024-02-29 14:39:54 192觀看
導(dǎo)讀前言大家好,我是田螺。最近一位朋友去拼夕夕面試,被問了這么一道題:限流算法有哪些?用代碼實(shí)現(xiàn)令牌桶算法。跟星球好友討論了一波,發(fā)現(xiàn)大家都忘記得差不多了.所以田螺哥再整理一波,常見的四種限流算法,以及簡單代碼實(shí)

前言

大家好,我是田螺。MFI28資訊網(wǎng)——每日最新資訊28at.com

最近一位朋友去拼夕夕面試,被問了這么一道題:限流算法有哪些?用代碼實(shí)現(xiàn)令牌桶算法。跟星球好友討論了一波,發(fā)現(xiàn)大家都忘記得差不多了.所以田螺哥再整理一波,常見的四種限流算法,以及簡單代碼實(shí)現(xiàn),相信大家看完,會茅塞頓開的。MFI28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片MFI28資訊網(wǎng)——每日最新資訊28at.com

1. 固定窗口限流算法

1.1 什么是固定窗口限流算法

固定窗口限流算法(Fixed Window Rate Limiting Algorithm)是一種最簡單的限流算法,其原理是在固定時(shí)間窗口(單位時(shí)間)內(nèi)限制請求的數(shù)量。該算法將時(shí)間分成固定的窗口,并在每個(gè)窗口內(nèi)限制請求的數(shù)量。具體來說,算法將請求按照時(shí)間順序放入時(shí)間窗口中,并計(jì)算該時(shí)間窗口內(nèi)的請求數(shù)量,如果請求數(shù)量超出了限制,則拒絕該請求。MFI28資訊網(wǎng)——每日最新資訊28at.com

假設(shè)單位時(shí)間(固定時(shí)間窗口)是1秒,限流閥值為3。在單位時(shí)間1秒內(nèi),每來一個(gè)請求,計(jì)數(shù)器就加1,如果計(jì)數(shù)器累加的次數(shù)超過限流閥值3,后續(xù)的請求全部拒絕。等到1s結(jié)束后,計(jì)數(shù)器清0,重新開始計(jì)數(shù)。如下圖:MFI28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片MFI28資訊網(wǎng)——每日最新資訊28at.com

1.2 固定窗口限流的偽代碼

public static Integer counter = 0;  //統(tǒng)計(jì)請求數(shù)   public static long lastAcquireTime =  0L;   public static final Long windowUnit = 1000L ; //假設(shè)固定時(shí)間窗口是1000ms   public static final Integer threshold = 10; // 窗口閥值是10       /**     * 固定窗口時(shí)間算法     * 關(guān)注公眾號:撿田螺的小男孩     * @return     */    public synchronized boolean fixedWindowsTryAcquire() {        long currentTime = System.currentTimeMillis();  //獲取系統(tǒng)當(dāng)前時(shí)間        if (currentTime - lastAcquireTime > windowUnit) {  //檢查是否在時(shí)間窗口內(nèi)            counter = 0;  // 計(jì)數(shù)器清0            lastAcquireTime = currentTime;  //開啟新的時(shí)間窗口        }        if (counter < threshold) {  // 小于閥值            counter++;  //計(jì)數(shù)統(tǒng)計(jì)器加1            return true;        }        return false;    }

1.2 固定窗口算法的優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):固定窗口算法非常簡單,易于實(shí)現(xiàn)和理解。
  • 缺點(diǎn):存在明顯的臨界問題,比如: 假設(shè)限流閥值為5個(gè)請求,單位時(shí)間窗口是1s,如果我們在單位時(shí)間內(nèi)的前0.8-1s和1-1.2s,分別并發(fā)5個(gè)請求。雖然都沒有超過閥值,但是如果算0.8-1.2s,則并發(fā)數(shù)高達(dá)10,已經(jīng)超過單位時(shí)間1s不超過5閥值的定義啦。

圖片圖片MFI28資訊網(wǎng)——每日最新資訊28at.com

2. 滑動窗口限流算法

2.1 什么是滑動窗口限流算法

滑動窗口限流算法是一種常用的限流算法,用于控制系統(tǒng)對外提供服務(wù)的速率,防止系統(tǒng)被過多的請求壓垮。它將單位時(shí)間周期分為n個(gè)小周期,分別記錄每個(gè)小周期內(nèi)接口的訪問次數(shù),并且根據(jù)時(shí)間滑動刪除過期的小周期。它可以解決固定窗口臨界值的問題。MFI28資訊網(wǎng)——每日最新資訊28at.com

用一張圖解釋滑動窗口算法,如下:MFI28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片MFI28資訊網(wǎng)——每日最新資訊28at.com

假設(shè)單位時(shí)間還是1s,滑動窗口算法把它劃分為5個(gè)小周期,也就是滑動窗口(單位時(shí)間)被劃分為5個(gè)小格子。每格表示0.2s。每過0.2s,時(shí)間窗口就會往右滑動一格。然后呢,每個(gè)小周期,都有自己獨(dú)立的計(jì)數(shù)器,如果請求是0.83s到達(dá)的,0.8~1.0s對應(yīng)的計(jì)數(shù)器就會加1。MFI28資訊網(wǎng)——每日最新資訊28at.com

我們來看下,滑動窗口,去解決固定窗口限流算法的臨界問題,思想是怎樣MFI28資訊網(wǎng)——每日最新資訊28at.com

假設(shè)我們1s內(nèi)的限流閥值還是5個(gè)請求,0.8~1.0s內(nèi)(比如0.9s的時(shí)候)來了5個(gè)請求,落在黃色格子里。時(shí)間過了1.0s這個(gè)點(diǎn)之后,又來5個(gè)請求,落在紫色格子里。如果是固定窗口算法,是不會被限流的,但是滑動窗口的話,每過一個(gè)小周期,它會右移一個(gè)小格。過了1.0s這個(gè)點(diǎn)后,會右移一小格,當(dāng)前的單位時(shí)間段是0.2~1.2s,這個(gè)區(qū)域的請求已經(jīng)超過限定的5了,已觸發(fā)限流啦,實(shí)際上,紫色格子的請求都被拒絕啦。MFI28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)滑動窗口的格子周期劃分的越多,那么滑動窗口的滾動就越平滑,限流的統(tǒng)計(jì)就會越精確。MFI28資訊網(wǎng)——每日最新資訊28at.com

2.2 滑動窗口限流算法的偽代碼實(shí)現(xiàn)

/**     * 單位時(shí)間劃分的小周期(單位時(shí)間是1分鐘,10s一個(gè)小格子窗口,一共6個(gè)格子)     */    private int SUB_CYCLE = 10;    /**     * 每分鐘限流請求數(shù)     */    private int thresholdPerMin = 100;    /**     * 計(jì)數(shù)器, k-為當(dāng)前窗口的開始時(shí)間值秒,value為當(dāng)前窗口的計(jì)數(shù)     */    private final TreeMap<Long, Integer> counters = new TreeMap<>();   /**     * 滑動窗口時(shí)間算法實(shí)現(xiàn)     */     public synchronized boolean slidingWindowsTryAcquire() {        long currentWindowTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) / SUB_CYCLE * SUB_CYCLE; //獲取當(dāng)前時(shí)間在哪個(gè)小周期窗口        int currentWindowNum = countCurrentWindow(currentWindowTime); //當(dāng)前窗口總請求數(shù)        //超過閥值限流        if (currentWindowNum >= thresholdPerMin) {            return false;        }        //計(jì)數(shù)器+1        counters.get(currentWindowTime)++;        return true;    }   /**    * 統(tǒng)計(jì)當(dāng)前窗口的請求數(shù)    */    private int countCurrentWindow(long currentWindowTime) {        //計(jì)算窗口開始位置        long startTime = currentWindowTime - SUB_CYCLE* (60s/SUB_CYCLE-1);        int count = 0;        //遍歷存儲的計(jì)數(shù)器        Iterator<Map.Entry<Long, Integer>> iterator = counters.entrySet().iterator();        while (iterator.hasNext()) {            Map.Entry<Long, Integer> entry = iterator.next();            // 刪除無效過期的子窗口計(jì)數(shù)器            if (entry.getKey() < startTime) {                iterator.remove();            } else {                //累加當(dāng)前窗口的所有計(jì)數(shù)器之和                count =count + entry.getValue();            }        }        return count;    }

2.3 滑動窗口限流算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 簡單易懂
  • 精度高(通過調(diào)整時(shí)間窗口的大小來實(shí)現(xiàn)不同的限流效果)
  • 可擴(kuò)展性強(qiáng)(可以非常容易地與其他限流算法結(jié)合使用)

缺點(diǎn):MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 突發(fā)流量無法處理(無法應(yīng)對短時(shí)間內(nèi)的大量請求,但是一旦到達(dá)限流后,請求都會直接暴力被拒絕。醬紫我們會損失一部分請求,這其實(shí)對于產(chǎn)品來說,并不太友好),需要合理調(diào)整時(shí)間窗口大小。

3. 漏桶限流算法

3.1 什么是漏桶限流算法

漏桶限流算法(Leaky Bucket Algorithm)是一種流量控制算法,用于控制流入網(wǎng)絡(luò)的數(shù)據(jù)速率,以防止網(wǎng)絡(luò)擁塞。它的思想是將數(shù)據(jù)包看作是水滴,漏桶看作是一個(gè)固定容量的水桶,數(shù)據(jù)包像水滴一樣從桶的頂部流入桶中,并通過桶底的一個(gè)小孔以一定的速度流出,從而限制了數(shù)據(jù)包的流量。MFI28資訊網(wǎng)——每日最新資訊28at.com

漏桶限流算法的基本工作原理是:對于每個(gè)到來的數(shù)據(jù)包,都將其加入到漏桶中,并檢查漏桶中當(dāng)前的水量是否超過了漏桶的容量。如果超過了容量,就將多余的數(shù)據(jù)包丟棄。如果漏桶中還有水,就以一定的速率從桶底輸出數(shù)據(jù)包,保證輸出的速率不超過預(yù)設(shè)的速率,從而達(dá)到限流的目的。MFI28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 流入的水滴,可以看作是訪問系統(tǒng)的請求,這個(gè)流入速率是不確定的。
  • 桶的容量一般表示系統(tǒng)所能處理的請求數(shù)。
  • 如果桶的容量滿了,就達(dá)到限流的閥值,就會丟棄水滴(拒絕請求)
  • 流出的水滴,是恒定過濾的,對應(yīng)服務(wù)按照固定的速率處理請求。

3.2 漏桶限流算法的偽代碼實(shí)現(xiàn)

/** * LeakyBucket 類表示一個(gè)漏桶, * 包含了桶的容量和漏桶出水速率等參數(shù), * 以及當(dāng)前桶中的水量和上次漏水時(shí)間戳等狀態(tài)。 */public class LeakyBucket {    private final long capacity;    // 桶的容量    private final long rate;        // 漏桶出水速率    private long water;             // 當(dāng)前桶中的水量    private long lastLeakTimestamp; // 上次漏水時(shí)間戳    public LeakyBucket(long capacity, long rate) {        this.capacity = capacity;        this.rate = rate;        this.water = 0;        this.lastLeakTimestamp = System.currentTimeMillis();    }    /**     * tryConsume() 方法用于嘗試向桶中放入一定量的水,如果桶中還有足夠的空間,則返回 true,否則返回 false。     * @param waterRequested     * @return     */    public synchronized boolean tryConsume(long waterRequested) {        leak();        if (water + waterRequested <= capacity) {            water += waterRequested;            return true;        } else {            return false;        }    }    /**     * 。leak() 方法用于漏水,根據(jù)當(dāng)前時(shí)間和上次漏水時(shí)間戳計(jì)算出應(yīng)該漏出的水量,然后更新桶中的水量和漏水時(shí)間戳等狀態(tài)。     */    private void leak() {        long now = System.currentTimeMillis();        long elapsedTime = now - lastLeakTimestamp;        long leakedWater = elapsedTime * rate / 1000;        if (leakedWater > 0) {            water = Math.max(0, water - leakedWater);            lastLeakTimestamp = now;        }    }}
  • 注意:   tryConsume() 和 leak() 方法中,都需要對桶的狀態(tài)進(jìn)行同步,以保證線程安全性。

3.3 漏桶限流算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 可以平滑限制請求的處理速度,避免瞬間請求過多導(dǎo)致系統(tǒng)崩潰或者雪崩。
  • 可以控制請求的處理速度,使得系統(tǒng)可以適應(yīng)不同的流量需求,避免過載或者過度閑置。
  • 可以通過調(diào)整桶的大小和漏出速率來滿足不同的限流需求,可以靈活地適應(yīng)不同的場景。

缺點(diǎn)MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 需要對請求進(jìn)行緩存,會增加服務(wù)器的內(nèi)存消耗。
  • 對于流量波動比較大的場景,需要較為靈活的參數(shù)配置才能達(dá)到較好的效果。
  • 但是面對突發(fā)流量的時(shí)候,漏桶算法還是循規(guī)蹈矩地處理請求,這不是我們想看到的啦。流量變突發(fā)時(shí),我們肯定希望系統(tǒng)盡量快點(diǎn)處理請求,提升用戶體驗(yàn)嘛。

4. 令牌桶算法

4.1 什么是令牌桶算法

令牌桶算法是一種常用的限流算法,可以用于限制單位時(shí)間內(nèi)請求的數(shù)量。該算法維護(hù)一個(gè)固定容量的令牌桶,每秒鐘會向令牌桶中放入一定數(shù)量的令牌。當(dāng)有請求到來時(shí),如果令牌桶中有足夠的令牌,則請求被允許通過并從令牌桶中消耗一個(gè)令牌,否則請求被拒絕。MFI28資訊網(wǎng)——每日最新資訊28at.com

4.2 令牌桶算法的偽代碼實(shí)現(xiàn)

/** * TokenBucket 類表示一個(gè)令牌桶 */public class TokenBucket {    private final int capacity;     // 令牌桶容量    private final int rate;         // 令牌生成速率,單位:令牌/秒    private int tokens;             // 當(dāng)前令牌數(shù)量    private long lastRefillTimestamp;  // 上次令牌生成時(shí)間戳    /**     * 構(gòu)造函數(shù)中傳入令牌桶的容量和令牌生成速率。     * @param capacity     * @param rate     */    public TokenBucket(int capacity, int rate) {        this.capacity = capacity;        this.rate = rate;        this.tokens = capacity;        this.lastRefillTimestamp = System.currentTimeMillis();    }    /**     * allowRequest() 方法表示一個(gè)請求是否允許通過,該方法使用 synchronized 關(guān)鍵字進(jìn)行同步,以保證線程安全。     * @return     */    public synchronized boolean allowRequest() {        refill();        if (tokens > 0) {            tokens--;            return true;        } else {            return false;        }    }    /**     * refill() 方法用于生成令牌,其中計(jì)算令牌數(shù)量的邏輯是按照令牌生成速率每秒鐘生成一定數(shù)量的令牌,     * tokens 變量表示當(dāng)前令牌數(shù)量,     * lastRefillTimestamp 變量表示上次令牌生成的時(shí)間戳。     */    private void refill() {        long now = System.currentTimeMillis();        if (now > lastRefillTimestamp) {            int generatedTokens = (int) ((now - lastRefillTimestamp) / 1000 * rate);            tokens = Math.min(tokens + generatedTokens, capacity);            lastRefillTimestamp = now;        }    }}

4.3 令牌桶算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 穩(wěn)定性高:令牌桶算法可以控制請求的處理速度,可以使系統(tǒng)的負(fù)載變得穩(wěn)定。
  • 精度高:令牌桶算法可以根據(jù)實(shí)際情況動態(tài)調(diào)整生成令牌的速率,可以實(shí)現(xiàn)較高精度的限流。
  • 彈性好:令牌桶算法可以處理突發(fā)流量,可以在短時(shí)間內(nèi)提供更多的處理能力,以處理突發(fā)流量。

Guava的RateLimiter限流組件,就是基于令牌桶算法實(shí)現(xiàn)的。MFI28資訊網(wǎng)——每日最新資訊28at.com

缺點(diǎn):MFI28資訊網(wǎng)——每日最新資訊28at.com

  • 實(shí)現(xiàn)復(fù)雜:相對于固定窗口算法等其他限流算法,令牌桶算法的實(shí)現(xiàn)較為復(fù)雜。對短時(shí)請求難以處理:在短時(shí)間內(nèi)有大量請求到來時(shí),可能會導(dǎo)致令牌桶中的令牌被快速消耗完,從而限流。這種情況下,可以考慮使用漏桶算法。
  • 時(shí)間精度要求高:令牌桶算法需要在固定的時(shí)間間隔內(nèi)生成令牌,因此要求時(shí)間精度較高,如果系統(tǒng)時(shí)間不準(zhǔn)確,可能會導(dǎo)致限流效果不理想。

總體來說,令牌桶算法具有較高的穩(wěn)定性和精度,但實(shí)現(xiàn)相對復(fù)雜,適用于對穩(wěn)定性和精度要求較高的場景。MFI28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-75311-0.html面試必備:四種經(jīng)典限流算法講解

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Vue2問題:分享一個(gè)通用多文件類型預(yù)覽庫

下一篇: 淺談鏈路聚合,你學(xué)會了嗎?

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 紅魔電競平板評測:大屏幕硬實(shí)力

    前言:三年的疫情因?yàn)橐暇W(wǎng)課的原因激活了平板市場,如今網(wǎng)課的時(shí)代已經(jīng)過去,大家的生活都恢復(fù)到了正軌,這也就意味著,真正考驗(yàn)平板電腦生存的環(huán)境來了。也就是面對著這種殘酷的
  • 2023年Q2用戶偏好榜:12+256G版本成新主流

    3月份的性能榜、性價(jià)比榜和好評榜之后,就要輪到2023年的第二季度偏好榜了,上半年的新機(jī)潮已經(jīng)過去,最明顯的肯定就是大內(nèi)存和存儲的機(jī)型了,另外部分中端機(jī)也取消了屏幕塑料支架
  • 6月iOS設(shè)備性能榜:M2穩(wěn)居榜首 A系列只能等一手3nm來救

    沒有新品發(fā)布,自然iOS設(shè)備性能榜的上榜設(shè)備就沒有什么更替,僅僅只有跑分變化而產(chǎn)生的排名變動,畢竟蘋果新品的發(fā)布節(jié)奏就是這樣的,一年下來也就幾個(gè)移動端新品,不會像安卓廠商,一
  • 一個(gè)注解實(shí)現(xiàn)接口冪等,這樣才優(yōu)雅!

    場景碼猿慢病云管理系統(tǒng)中其實(shí)高并發(fā)的場景不是很多,沒有必要每個(gè)接口都去考慮并發(fā)高的場景,比如添加住院患者的這個(gè)接口,具體的業(yè)務(wù)代碼就不貼了,業(yè)務(wù)偽代碼如下:圖片上述代碼有
  • 零售大模型“干中學(xué)”,攀爬數(shù)字化珠峰

    文/侯煜編輯/cc來源/華爾街科技眼對于絕大多數(shù)登山愛好者而言,攀爬珠穆朗瑪峰可謂終極目標(biāo)。攀登珠峰的商業(yè)路線有兩條,一是尼泊爾境內(nèi)的南坡路線,一是中國境內(nèi)的北坡路線。相
  • 最“俊美”淘寶賣家,靠直播和短視頻圈粉,上架秒光,年銷3000萬

    來源 | 電商在線文|易琬玉編輯|斯問受訪店鋪:Ringdoll戒之人形圖源:微博@御座的黃山、&ldquo;Ringdoll戒之人形&rdquo;淘寶店鋪有關(guān)外貌的評價(jià),黃山已經(jīng)聽累了。生于1985年的他,哪
  • 東方甄選單飛:有些鳥注定是關(guān)不住的

    文/彭寬鴻編輯/羅卿東方甄選創(chuàng)始人俞敏洪帶隊(duì)的&ldquo;7天甘肅行&rdquo;直播活動已在近日順利收官。成立后一年多時(shí)間里,東方甄選要脫離抖音自立門戶的傳聞不絕于耳,&ldquo;7
  • iQOO Neo8 Pro評測:旗艦雙芯加持 最強(qiáng)性能游戲旗艦

    【Techweb評測】去年10月,iQOO推出了一款Neo7手機(jī),該機(jī)搭載了聯(lián)發(fā)科天璣9000+,配備獨(dú)顯芯片Pro+,帶來了同價(jià)位段最佳的游戲體驗(yàn),一經(jīng)上市便受到了諸多用
  • 微軟發(fā)布Windows 11新版 引入全新任務(wù)欄狀態(tài)

    近日,微軟發(fā)布了Windows 11新版,而Build 22563更新主要引入了幾周前曝光的平板模式任務(wù)欄等,系統(tǒng)更流暢了。更新中,Windows 11加入了專門針對平板優(yōu)化的任務(wù)欄
Top 主站蜘蛛池模板: 通城县| 始兴县| 沿河| 乳山市| 珠海市| 普格县| 略阳县| 内乡县| 交城县| 博乐市| 浮梁县| 台中县| 乐清市| 杭锦后旗| 桐梓县| 四平市| 南康市| 钟祥市| 嵩明县| 平安县| 伊春市| 灌云县| 沅陵县| 绵阳市| 扶绥县| 松潘县| 琼海市| 广水市| 静乐县| 大城县| 福海县| 眉山市| 新郑市| 响水县| 临沧市| 南陵县| 班玛县| 涟水县| 无棣县| 保定市| 襄樊市|