- 對請求的目標(biāo)URL進行限流(例如:某個URL每分鐘只允許調(diào)用多少次)
- 對客戶端的訪問IP進行限流(例如:某個IP每分鐘只允許請求多少次)
- 對某些特定用戶或者用戶組進行限流(例如:非VIP用戶限制每分鐘只允許調(diào)用100次某個API等)
- 多維度混合的限流。此時纯路,就需要實現(xiàn)一些限流規(guī)則的編排機制。與愈腾、或、非等關(guān)系评架。
介紹
spring-cloud-zuul-ratelimit是和zuul整合提供分布式限流策略的擴展,只需在yaml中配置幾行配置,就可使應(yīng)用支持限流
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>1.3.4.RELEASE</version>
</dependency>
支持的限流粒度
服務(wù)粒度 (默認(rèn)配置辨泳,當(dāng)前服務(wù)模塊的限流控制)
用戶粒度 (詳細(xì)說明虱岂,見文末總結(jié))
ORIGIN粒度 (用戶請求的origin作為粒度控制)
接口粒度 (請求接口的地址作為粒度控制)
以上粒度自由組合玖院,又可以支持多種情況菠红。
如果還不夠,自定義RateLimitKeyGenerator實現(xiàn)难菌。
//默認(rèn)實現(xiàn)
public String key(final HttpServletRequest request, final Route route, final RateLimitProperties.Policy policy) {
final List<Type> types = policy.getType();
final StringJoiner joiner = new StringJoiner(":");
joiner.add(properties.getKeyPrefix());
if (route != null) {
joiner.add(route.getId());
}
if (!types.isEmpty()) {
if (types.contains(Type.URL) && route != null) {
joiner.add(route.getPath());
}
if (types.contains(Type.ORIGIN)) {
joiner.add(getRemoteAddr(request));
}
// 這個結(jié)合文末總結(jié)试溯。
if (types.contains(Type.USER)) {
joiner.add(request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : ANONYMOUS_USER);
}
}
return joiner.toString();
}
支持的存儲方式
image
- InMemoryRateLimiter - 使用 ConcurrentHashMap作為數(shù)據(jù)存儲
- ConsulRateLimiter - 使用 Consul 作為數(shù)據(jù)存儲
- RedisRateLimiter - 使用 Redis 作為數(shù)據(jù)存儲
- SpringDataRateLimiter - 使用 數(shù)據(jù)庫 作為數(shù)據(jù)存儲
限流配置
- limit 單位時間內(nèi)允許訪問的個數(shù)
- quota 單位時間內(nèi)允許訪問的總時間(統(tǒng)計每次請求的時間綜合)
- refresh-interval 單位時間設(shè)置
zuul:
ratelimit:
key-prefix: your-prefix
enabled: true
repository: REDIS
behind-proxy: true
policies:
myServiceId:
limit: 10
quota: 20
refresh-interval: 30
type:
- user
以上配置意思是:30秒內(nèi)允許10個訪問,并且要求總請求時間小于20秒
效果展示
yaml配置:
zuul:
ratelimit:
key-prefix: pig-ratelimite
enabled: true
repository: REDIS
behind-proxy: true
policies:
pig-admin-service:
limit: 2
quota: 1
refresh-interval: 3
動態(tài)圖 ↓↓↓↓↓
image
Redis 中數(shù)據(jù)結(jié)構(gòu) 注意紅色字體
image
總結(jié)
- 可以使用Spring Boot Actuator 提供的服務(wù)狀態(tài)郊酒,動態(tài)設(shè)置限流開關(guān)
- 源碼可以參考:https://gitee.com/log4j/pig
- 用戶限流的實現(xiàn):如果你的項目整合 Shiro 或者 Spring Security 安全框架遇绞,那么會自動維護request域UserPrincipal,如果是自己的框架燎窘,請登錄成功后維護request域UserPrincipal摹闽,才能使用用戶粒度的限流。未登錄默認(rèn)是:anonymous