Use redis key hash tags for redis cluster support.
fixes gh-248
This commit is contained in:
@@ -10,6 +10,9 @@ import javax.validation.constraints.Min;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -18,9 +21,6 @@ import org.springframework.data.redis.core.script.RedisScript;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* See https://stripe.com/blog/rate-limiters and
|
||||
* https://gist.github.com/ptarjan/e38f45f2dfe601419ca3af937fff574d#file-1-check_request_rate_limiter-rb-L11-L34
|
||||
@@ -102,11 +102,8 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
|
||||
int burstCapacity = routeConfig.getBurstCapacity();
|
||||
|
||||
try {
|
||||
// Make a unique key per user.
|
||||
String prefix = "request_rate_limiter." + id;
|
||||
List<String> keys = getKeys(id);
|
||||
|
||||
// You need two Redis keys for Token Bucket.
|
||||
List<String> keys = Arrays.asList(prefix + ".tokens", prefix + ".timestamp");
|
||||
|
||||
// The arguments to the LUA script. time() returns unixtime in seconds.
|
||||
List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
|
||||
@@ -141,6 +138,19 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
|
||||
return Mono.just(new Response(true, -1));
|
||||
}
|
||||
|
||||
static List<String> getKeys(String id) {
|
||||
// use `{}` around keys to use Redis Key hash tags
|
||||
// this allows for using redis cluster
|
||||
|
||||
// Make a unique key per user.
|
||||
String prefix = "request_rate_limiter.{" + id;
|
||||
|
||||
// You need two Redis keys for Token Bucket.
|
||||
String tokenKey = prefix + "}.tokens";
|
||||
String timestampKey = prefix + "}.timestamp";
|
||||
return Arrays.asList(tokenKey, timestampKey);
|
||||
}
|
||||
|
||||
@Validated
|
||||
public static class Config {
|
||||
@Min(1)
|
||||
|
||||
@@ -71,6 +71,12 @@ public class RedisRateLimiterTests extends BaseWebClientTests {
|
||||
response = rateLimiter.isAllowed(routeId, id).block();
|
||||
assertThat(response.isAllowed()).as("steady state # %s is allowed", replenishRate).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keysUseRedisKeyHashTags() {
|
||||
assertThat(RedisRateLimiter.getKeys("1"))
|
||||
.containsExactly("request_rate_limiter.{1}.tokens", "request_rate_limiter.{1}.timestamp");
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
|
||||
Reference in New Issue
Block a user