feat:修改ratelimiter的重复创建问题
This commit is contained in:
parent
10cfb0fc56
commit
c2a13cabf6
@ -1,31 +1,22 @@
|
|||||||
package cn.axzo.pokonyan.client;
|
package cn.axzo.pokonyan.client;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public interface RateLimiter {
|
public interface RateLimiter {
|
||||||
/**
|
/**
|
||||||
* 尝试获得锁, 获取失败则返回Optional.empty()
|
* 尝试获得锁, 获取失败则返回Optional.empty()
|
||||||
* 如果获取锁成功. 则返回Optional<Permit>. 同时计数器增加
|
* 如果获取锁成功. 则返回Optional<Permit>. 同时计数器增加
|
||||||
* Permit支持取消
|
* Permit支持取消
|
||||||
*
|
|
||||||
* @param value 业务标识
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean tryAcquire(Object value);
|
boolean tryAcquire();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取窗口类型
|
* 获取窗口类型
|
||||||
|
|||||||
@ -24,12 +24,13 @@ public class RedisRateLimiterImpl implements RateLimiter {
|
|||||||
private LimitRule limitRule;
|
private LimitRule limitRule;
|
||||||
private WindowType windowType;
|
private WindowType windowType;
|
||||||
|
|
||||||
|
private RRateLimiter rateLimiter;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
RedisRateLimiterImpl(RedissonClient redissonClient,
|
RedisRateLimiterImpl(RedissonClient redissonClient,
|
||||||
WindowType windowType,
|
WindowType windowType,
|
||||||
String limiterKey,
|
String limiterKey,
|
||||||
LimitRule limitRule,
|
LimitRule limitRule) {
|
||||||
Integer maxWindowDurationHour) {
|
|
||||||
Objects.requireNonNull(redissonClient);
|
Objects.requireNonNull(redissonClient);
|
||||||
Objects.requireNonNull(windowType);
|
Objects.requireNonNull(windowType);
|
||||||
Objects.requireNonNull(limitRule);
|
Objects.requireNonNull(limitRule);
|
||||||
@ -43,11 +44,16 @@ public class RedisRateLimiterImpl implements RateLimiter {
|
|||||||
this.limitRule = limitRule;
|
this.limitRule = limitRule;
|
||||||
this.limiterKey = limiterKey;
|
this.limiterKey = limiterKey;
|
||||||
this.rateLimiterWorker = buildWorker(windowType);
|
this.rateLimiterWorker = buildWorker(windowType);
|
||||||
|
|
||||||
|
String key = buildRedisKey();
|
||||||
|
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
|
||||||
|
rateLimiter.trySetRate(RateType.OVERALL, limitRule.getPermits(), limitRule.getSeconds(), RateIntervalUnit.SECONDS);
|
||||||
|
this.rateLimiter = rateLimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryAcquire(Object value) {
|
public boolean tryAcquire() {
|
||||||
return rateLimiterWorker.tryAcquire(value);
|
return rateLimiterWorker.tryAcquire();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -62,10 +68,9 @@ public class RedisRateLimiterImpl implements RateLimiter {
|
|||||||
throw new RuntimeException(String.format("unsupported window type, window type = %s", windowType));
|
throw new RuntimeException(String.format("unsupported window type, window type = %s", windowType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildRedisKey(Object value) {
|
private String buildRedisKey() {
|
||||||
String hash = Hashing.murmur3_128().newHasher()
|
String hash = Hashing.murmur3_128().newHasher()
|
||||||
.putString(limiterKey, Charsets.UTF_8)
|
.putString(limiterKey, Charsets.UTF_8)
|
||||||
.putString(String.valueOf(value), Charsets.UTF_8)
|
|
||||||
.hash()
|
.hash()
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
@ -81,14 +86,7 @@ public class RedisRateLimiterImpl implements RateLimiter {
|
|||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
class SlidingWindowRateLimiter implements RateLimiterWorker {
|
class SlidingWindowRateLimiter implements RateLimiterWorker {
|
||||||
public boolean tryAcquire(Object value) {
|
public boolean tryAcquire() {
|
||||||
String key = buildRedisKey(value);
|
|
||||||
|
|
||||||
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
|
|
||||||
if (!rateLimiter.isExists()) {
|
|
||||||
rateLimiter.trySetRate(RateType.OVERALL, limitRule.getPermits(), limitRule.getSeconds(), RateIntervalUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rateLimiter.tryAcquire(1);
|
return rateLimiter.tryAcquire(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,9 +95,8 @@ public class RedisRateLimiterImpl implements RateLimiter {
|
|||||||
/**
|
/**
|
||||||
* 尝试获取令牌
|
* 尝试获取令牌
|
||||||
*
|
*
|
||||||
* @param value
|
|
||||||
* @return 如果获取成功则返回true, 失败则为false
|
* @return 如果获取成功则返回true, 失败则为false
|
||||||
*/
|
*/
|
||||||
boolean tryAcquire(Object value);
|
boolean tryAcquire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user