令牌桶演算法原理及實現(圖文詳解)

張哥說技術發表於2023-02-28

在高併發的場景裡,由於突發流量過大,經常會限流,而限流就會涉及到具體的演算法,令牌桶演算法就是一種限流演算法,今天分享令牌桶演算法。


令牌桶簡介

令牌桶,英文名token bucket,可以看作是一個存放令牌的容器,預先設定一定的容量,系統按設定的速度向桶中放置令牌,當桶中令牌滿時,多餘的令牌溢位。

如下圖所示:

令牌桶演算法原理及實現(圖文詳解)

 

為什麼需要令牌桶?

在高併發系統,比如大家熟知的秒殺,這個時候有大量的使用者在同一時間大量湧入,這個時候很可能會超過系統的承受能力,這個就需要考慮限流了。

而令牌桶演算法就是限流的一種策略,是進行流量限制的一種常用演算法,常用於控制傳送到網路上的資料的數量,並允許突發資料的傳送。

為了保證系統的穩定執行,一旦達到的需要限制的閾值,就需要限制流量並採取一些措施以完成限制流量的目的,比如:延遲處理,拒絕處理,或者部分拒絕處理等等。

 

令牌桶演算法原理

令牌桶演算法的原理是系統會以一個恆定的速度往桶裡放入令牌,如果請求需要被處理,則需要先從桶裡獲取一個令牌,當桶滿時新新增的令牌被丟棄或拒絕。

令牌桶演算法流程,如下圖所示:

令牌桶演算法原理及實現(圖文詳解)

令牌桶演算法流程,大致分為如下三步:

第一步:放入令牌到桶

按照固定的速率被放入令牌桶中,比如每秒放10個、100個、1000個令牌到桶中。

 

第二步:獲取令牌

所有的請求在處理之前都需要拿到一個可用的令牌才會被處理。

 

第三步 :令牌桶滿了拒絕

比如:桶中最多能放10000個令牌,當桶滿時,就不能繼續放入了,新新增的令牌要麼被丟棄,要麼就直接拒絕。

 

令牌桶演算法實現

可以使用google提供的guava工具來實現。

<dependency>    <groupId>com.google.guava</groupId>    <artifactId>guava</artifactId></dependency>
// 每秒生成2個令牌RateLimiter rateLimiter = RateLimiter.create(2);for (int i = 0; i < 6; i++) {    new Thread(() -> {        // 獲得令牌        rateLimiter.acquire();        System.out.println(LocalDateTime.now());    }).start();}

可以透過RateLimiter限流元件來實現。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2937357/,如需轉載,請註明出處,否則將追究法律責任。

相關文章