技術分享 一文了解高併發限流演算法

2021-10-09 13:06:50 字數 3160 閱讀 6265

作為熱點頻出的電商系統,經常遇到高併發,熱點秒殺的場景。我們在開發設計高併發海量業務請求的系統時,通常利用三板斧:快取、降級和限流來保障系統穩定性。

快取:使業務資料更靠近資料的使用者,提公升程式訪問資料速度和增大系統qps容量。

降級:當系統容量達到一定健康閾值時根據當前業務情況及流量對一些服務和頁面有策略的降級,以此釋放伺服器資源以保證核心任務的正常執行。

限流:通過對併發訪問/請求進行限速,或者對乙個時間視窗內的請求進行限速來保護系統穩定可用,一旦達到限制速率則可以拒絕服務、排隊或等待、降級等處理。

本文聊聊限流的常用演算法,並且通過案例測試驗證令牌桶演算法。

目前程式開發過程常用的限流演算法有兩個:漏桶演算法和令牌桶演算法

漏桶演算法

漏桶演算法的原理比較簡單,請求進入到漏桶中,漏桶以一定的速率漏水。當請求過多時,水直接溢位。可以看出,漏桶演算法可以強制限制資料的傳輸速度。

如圖所示,把請求比作是水滴,水先滴到桶裡,通過漏洞並以限定的速度出水,當水來得過猛而出水不夠快時就會導致水直接溢位,即拒絕服務。

來自網路

漏桶的出水速度是恆定的,那麼意味著如果瞬時大流量的話,將有大部分請求被丟棄掉(也就是所謂的溢位)。

令牌桶演算法

令牌桶演算法的原理是系統以一定速率向桶中放入令牌,如果有請求時,請求會從桶中取出令牌,如果能取到令牌,則可以繼續完成請求,否則等待或者拒絕服務。這種演算法可以應對突發程度的請求,因此比漏桶演算法好。

來自網路

漏桶演算法和令牌桶演算法的選擇

兩者的主要區別漏桶演算法能夠強行限制處理資料的速率,不論系統是否空閒。而令牌桶演算法能夠在限制資料的平均處理速率的同時還允許某種程度的突發流量。

如何理解上面的含義呢?

漏桶演算法 比如系統吞吐量是 120/s,業務請求 130/s,使用漏斗限流 100/s,起到限流的作用,多餘的請求將產生等待或者丟棄。

對於令牌桶演算法,每秒產生 100 個令牌,系統容量 200 個令牌。正常情況下,業務請求 100/s 時,請求能被正常被處理。當有突發流量過來比如 200 個請求時,因為系統容量有 200 個令牌可以同一時刻處理掉這 200 個請求。如果是漏桶演算法,則只能處理 100 個請求,其他的請求等待或者被丟棄。

本案例使用 python 基於令牌桶演算法進行測試。

# encoding: utf-8

"""author: [email protected]

time: 2020/9/9 10:43 pm

func:

"""import time

import multiprocessing

test = 每秒產生的令牌數量

'all': ,

'test2': ,

'test3': ,

'test4': ,#表示突發100個請求

'test5': ,#表示突發200個請求

'test6': ,

}}class tokenbucket(object):

# rate是令牌發放速度,capacity是桶的大小

def __init__(self, rate, capacity):

self._rate = rate

self._capacity = capacity

self._current_amount = 0

self._last_consume_time = int(time.time())

# token_amount是傳送資料需要的令牌數

def consume(self, token_amount):

time.sleep(1)

# 計算從上次傳送到這次傳送,新發放的令牌數量

increment = (int(time.time()) - self._last_consume_time) * self._rate

# 令牌數量不能超過桶的容量

self._current_amount = min(

increment + self._current_amount, self._capacity)

# 如果沒有足夠的令牌,則不能傳送資料

if token_amount > self._current_amount:

return false

self._last_consume_time = int(time.time())

self._current_amount -= token_amount

return true

def job():

i = 100

while i>1:

for result in result_dict.values():

key = tuple(result.keys())[0]

rate = tuple(result.values())[0]

i = i-1

if i <= 0:

break

if not limiter.consume(rate):

print(key + ' 限流')

else:

print(key + ' 正常')

def run():

threads = [multiprocessing.process(target=job) for i in range(3)]

for thread in threads:

thread.start()

if __name__ == '__main__':

result_dict = test["all"]

rate = 30

capacity = 120

limiter = tokenbucket(rate, capacity)

run()

這段測試**比較簡單,大家可以結合自己的業務場景在編寫工具時看看**可以使用到限流演算法。

爬蟲 一文了解反反爬蟲及其相關技術

那麼什麼又是反爬蟲呢?反爬蟲是指使用任何技術手段阻止別人批量獲取自己 資訊的一種方式。不返回網頁是比較傳統的反爬蟲手段,也就是在爬蟲傳送請求給相應 位址後,返回404頁面,表示伺服器無法正常提供資訊或伺服器無法回應 也可能長時間不返回資料,這代表對爬蟲已經進行了 例如去哪兒網的 你有張良計,我有過梁...

一文全面了解NB IoT技術優勢及特點

1 nb iot多輸入多輸出技術 nb iot可以利用多天線技術抑制通道傳輸衰弱,獲得分集增益 空間復用增益和陣列增益,在傳送端和接收端均採用多天線實現訊號同時傳送和接收 因此就形成了乙個並行的多空間通道,充分利用空間通道傳輸資源,在不增加系統頻寬和天線發射總功率的條件下提供空間分集增益,在多徑衰落...

高併發之限流令牌桶和漏桶演算法(一)

在開發高併發系統時有三把利器用來保護系統 快取 降級和限流 漏桶演算法思路很簡單,水 請求 先進入到漏桶裡,漏桶以一定的速度出水,當水流入速度過大會直接溢位,可以看出漏桶演算法能強行限制資料的傳輸速率。下面時偽 public class tokenbucketdemo else 漏桶演算法不能夠有效...