註解反思
我們專案有好幾個介面,呼叫公司中颱的介面,包括定時器的分片執行還有本人的多執行緒強行壓榨,哈哈。最後加上使用者的瘋狂請求,導致中颱的介面偶爾出現問題,主要是資料庫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,導致響應速度降低或者超時,甚至可能英雌導致伺服器宕機,尤其是資料庫伺服器。所以就有限流的思想,限制客戶端對伺服器端端的請求限制,如果在單位時間內超過該請求限制,就會執...