基於Redis介面限流策略

2021-10-16 02:11:30 字數 4166 閱讀 8166

暴力限流依據redis中key,只儲存訪問人數並設定乙個過期時間,當key值大於規定人數則限流。有乙個弊端:生成key時候訪問人數很少,當key還有一秒即將過期,現在來了很多請求,結果key過期了,又產生乙個key值從0開始,這時伺服器承擔兩倍的壓力。而下面滑動視窗可以解決這個問題。

自定義註解加aop方式

通過方法或類上註解攔截請求方法是否需要限流(方法註解優先類上註解),如果有規定時間內大於配置請求數量就丟擲異常。

因為我們機器是集群狀態,所以必須用redis做限流,可以避免併發等問題。

**

/**

* @author: lailaimonkey

* @description:

* @date:created in 2021-01-13 14:41

* @modifi ed by:

*/@documented

@target()

@retention

(retentionpolicy.runtime)

public @inte***ce

accesslimit

/**

* @author: lailaimonkey

* @description:

* @date:created in 2021-01-13 14:43

* @modified by:

*/@component

@aspect

public

class

ratelimitaop

@around

("servicelimit()"

)public object around

(proceedingjoinpoint joinpoint)

throws throwable

//是否進行限流

boolean pass =

redislimit

(rate_limit_key + requesturi, accesslimit.

limit()

, accesslimit.

time()

);if(pass)

return joinpoint.

proceed()

;}/** * 是否進行限流,true:限流,false:不限流

** @param key

* @param limit

* @param time

* @return

*/private

boolean

redislimit

(string key,

int limit,

int time)

/** * lua限流指令碼

* ar**[1] 過期時間

*/private string buildslidewindowlimitluascript()

}

@accesslimit

@restcontroller

public

class

tbldeptcontroller

}

滑動視窗演算法是在給定視窗大小情況下計算結果操作。

基於redis滑動視窗限流我們可以用zset陣列,當每一次請求進來的時候,我們可以給指定key值 生成乙個value和score。value保持唯一,可以用uuid生成。score可以用當前時間戳表示。因為zset資料結構也提供了range方法可以讓我們統計2個時間間隔中有多少個請求。

自定義註解加aop方式

通過方法或類上註解攔截請求方法是否需要限流(方法註解優先類上註解),如果有規定時間內大於配置請求數量就丟擲異常。

因為我們機器是集群狀態,所以必須用redis做限流,可以避免併發等問題。

**

/**

* @author: lailaimonkey

* @description:

* @date:created in 2021-01-13 14:43

* @modified by:

*/@component

@aspect

public

class

ratelimitaop

@around

("servicelimit()"

)public object around

(proceedingjoinpoint joinpoint)

throws throwable

//是否進行限流

boolean pass =

redislimit

(rate_limit_key + requesturi, accesslimit.

limit()

, accesslimit.

time()

);if(pass)

return joinpoint.

proceed()

;}/** * 是否進行限流,true:限流,false:不限流

** @param key

* @param limit

* @param time

* @return

*/private

boolean

redislimit

(string key,

int limit,

int time)

/** * lua限流指令碼

* ar**[1] uuid

* ar**[2] 當前時間戳

* ar**[3] 當前時間戳-視窗時間

* ar**[4] 限制的大小

*/private string buildslidewindowlimitluascript()

}

每隔一段時間系統往桶中放一定數量令牌,如果令牌已經滿了停止放入。使用者訪問介面先獲取令牌,獲得令牌可以訪問,否則拒絕訪問。

**這時註解中引數已經不起作用了,所有引數由定時器控制。

@autowired

private redistemplate redistemplate;

//每秒放乙個令牌

@scheduled

(fixeddelay =

1000

, initialdelay =

1000

)public

void

setintervaltimetask()

}

/**

* @author: lailaimonkey

* @description:

* @date:created in 2021-01-13 14:43

* @modified by:

*/@component

@aspect

public

class

ratelimitaop

@around

("servicelimit()"

)public object around

(proceedingjoinpoint joinpoint)

throws throwable

//是否進行限流

boolean pass =

redislimit

(rate_limit_key + requesturi, accesslimit.

limit()

, accesslimit.

time()

);if(pass)

return joinpoint.

proceed()

;}/** * 是否進行限流,true:限流,false:不限流

** @param key

* @param limit

* @param time

* @return

*/private

boolean

redislimit

(string key,

int limit,

int time)

}

nginx限流策略

參考 limit req zone binary remote addr zone mylimit 10m rate 2r s server binary remote addr 表示針對每個ip限流 zone mylimit 10m 表示建立乙個大小為 10m 的名為 mylimit 的記憶體區域...

基於Redis的分布式服務限流

基於redis快取的分布式服務限流 1 定於限流註解,限流註解可以加需要限流的業務類上,value為限流業務型別 target elementtype.method retention retentionpolicy.runtime public inte ce tpscontrol2 限流配置類,...

Redis 簡單限流

首先我們來看乙個常見 的簡單的限流策略。系統要限定使用者的某個行為在指定的時間裡只能允許發生 n 次,如何使用 redis 的資料結構來實現這個限流的功能?這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要...