暴力限流依據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 來圈出這個時間視窗來。而且我們只需要...