通過使用註解(提供介面形式與引數形式2種方式)針對性的對介面進行限流,底層使用redis配合lua指令碼實現令牌桶。
public
class
redisratelimiter
public
boolean
tryacquire
(string flag, int maxpermits, int addrate,
long expireseconds)
});long count = (long) execute;
return count != 0;
} private string buildluascript()}
複製**
為什麼使用hash:使用集群版redis時,必須使所有key在1個slot上。
@target()
@retention(retentionpolicy.runtime)
public
@inte***ce enableredisratelimiter
複製**
demo.flag=
demo.params=demo
demo.maxpermits=10
demo.addrate=1
demo.expireseconds=10
複製**
此配置檔案供下文redisratelimiterconfigmanager類使用
@configuration
public
class
redisratelimiterconfiguration
implements
else
} @override
public
void
throws bean***ception
}複製**
redistemplate類注入**省略,整合jedis。
@aspect
@component
public
class
redisratelimiteraspect
string paramnames = paramname.split(",");
string argnames = methodsignature.getparameternames(); // 引數名
object args = joinpoint.getargs();// 引數值
flag = arrays.stream(paramnames).map(p -> catch (exception e) }}
return
null;
}).filter(objects::nonnull)
.collect(collectors.joining(":"));
}if (stringutil.isnullorempty(flag))
string strmaxpermits = redisratelimiterconfigmanager
.getproperty(combinekey(key, max_permits_suffix));
int maxpermits = stringutil.isnullorempty(strmaxpermits) ? 0
: integer.parseint(strmaxpermits);
string straddrate = redisratelimiterconfigmanager
.getproperty(combinekey(key, add_rate_suffix));
int addrate = stringutil.isnullorempty(straddrate) ? 0
: integer.parseint(straddrate);
string strexpireseconds = redisratelimiterconfigmanager
.getproperty(combinekey(key, expire_seconds_suffix));
long expireseconds = stringutil.isnullorempty(strexpireseconds)
? 0: integer.parseint(strexpireseconds);
string finalflag = key + ":" + flag;
boolean success = redisratelimiter.tryacquire(finalflag,
maxpermits, addrate, expireseconds);
if (!success)
}} }
public string combinekey
(string key, string suffix)
}複製**
上述**中redisratelimiterconfigmanager**省略,內部實現為通過combinekey方法後的值去獲取對應的配置檔案中value。 使用ratelimitj進行api的限流
對外發布的api非常有必要進行流控,防止惡意攻擊,從而盡可能地保護系統。ratelimitj是乙個非常好的開源專案,提供了基於redis hazelcast inmemory版本的實現方案。這裡簡單演示一下如何使用inmemory版本。es.moki.ratelimitj ratelimitj co...
Redis 簡單限流
首先我們來看乙個常見 的簡單的限流策略。系統要限定使用者的某個行為在指定的時間裡只能允許發生 n 次,如何使用 redis 的資料結構來實現這個限流的功能?這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要...
redis簡單限流
需求 如果要保證乙個使用者一分鐘內只能訪問5次介面,超過就拒絕範圍。這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要保留這個時間視窗,視窗之外的資料都可以砍掉。那這個 zset 的 value 填什麼比較...