redis lua分布式限流

2021-10-03 09:15:52 字數 1839 閱讀 8200

註解反思

我們專案有好幾個介面,呼叫公司中颱的介面,包括定時器的分片執行還有本人的多執行緒強行壓榨,哈哈。最後加上使用者的瘋狂請求,導致中颱的介面偶爾出現問題,主要是資料庫cpu達到100%。

昨晚專門做了個限流,那麼技術定型使用什麼呢?ratelimiter?這好像是單機才能玩,sentinel?這個還要搭建環境。那就只能redis+lua。

lua指令碼放在resource目錄下

local key = keys[1];

local limit = tonumber(ar**[1]);

local val = redis.call("incrby", key,"1");

if val == 1 then

redis.call("expire", key,"1")

return 1;

endif val > limit then

return 0;

endreturn 1;

意思:incrby自增乙個key,如果是1的話,證明剛剛設定,需要設定過期時間為1秒,如果不是的話返回1,再如果超過我們限制的limit值,那麼返回0,表示限流。

計數法啦,當然簡單也有缺點。

@slf4j

@component

public class redislimit

/*** 1秒內限流

** @param key

* @param limit

* @return true 放行 false gg

*/public boolean accquire(string key, integer limit)

//list設定lua的keys

listkeylist = new arraylist<>();

keylist.add(string.format(cache_key, key));

// 執行lua指令碼,傳入引數

long result = (long) (redistemplate.execute(get_redis_script, keylist, limit));

system.out.println(result);

return result == 1;

}}

解析一下

使用redistemplate.execute來執行lua了,注意這裡有個坑,如果你是直接去拿connect連線的,記得要釋放資源,在spring與redis整合比較低的版本是沒有說去釋放資源的!!!

為了通用使用aop註解

方法註解頭

@target()

@retention(retentionpolicy.runtime) // 保留到執行時,可通過註解獲取

@documented

public @inte***ce myredislimit

乙個是快取的key,乙個是限制最大的數量limit,這裡不能用integer.

aop邏輯

@aspect

@component

public class testaspect

@before(value = "annotationpoincut()")

public void beforetest(joinpoint point)

}}

到此完成了,但是記住加上這個註解,必須使用spring注入去呼叫,如果是本地方法一樣呼叫的話,這個註解就失效了!

redis Lua實現分布式鎖

1.方法lock string lock,int expire 獲取鎖 expire,鎖的過期時間 setnx 只有當lock不存在時才會賦值,賦值成功返回1,賦值失敗返回0 public boolean lock string lock,int expire throws exception2.方...

分布式限流實戰

由於api介面無法控制呼叫方的行為,因此當遇到瞬時請求量激增時,會導致介面占用過多伺服器資源,使得其他請求響應速度降低或是超時,更有甚者可能導致伺服器宕機。限流 rate limiting 指對應用服務的請求進行限制,例如某一介面的請求限制為100個每秒,對超過限制的請求則進行快速失敗或丟棄。限流可...

分布式限流演算法

一 限流的作用 有高併發的系統中,由於api介面無法控制呼叫發的行為,因此如果遇到瞬時請求數量遞增,就會導致介面占用過多的伺服器子u,導致響應速度降低或者超時,甚至可能英雌導致伺服器宕機,尤其是資料庫伺服器。所以就有限流的思想,限制客戶端對伺服器端端的請求限制,如果在單位時間內超過該請求限制,就會執...