使用Redis進行限流

2021-09-24 07:53:55 字數 2565 閱讀 1774

通過使用註解(提供介面形式與引數形式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 填什麼比較...