The background,
The Soul gateway provides three plug-ins for traffic limiting
- RateLimiter relies on the token bucket made by Redis
- Hystrix is based on RxJava and has not been updated for several years. It is probably mature and stable, and there is no need to update
- Sentinel Ali open source
- After the suspension of The Resilience4J Hystrix, Netflix recommended to move to The Resilience4J framework, which is a lightweight, easy-to-use, and assemblable high availability framework that supports multiple high availability mechanisms such as circuit breaker, high frequency control, isolation, flow limiting, time limiting, and retry.
I got a comparison from the Internet
Sensory learning Soul gateway, as the gateway to distributed services, to learn all around the technology. Microprofile. IO /, it turns out that the world of distributed services is not just Spring or Service Mech. MicroProfile has several microservice-like specifications endorsed by IBM, Red Hat, and an open source community implementation project supported by Red Hat. Here is an article introduces my.oschina.net/u/4567873/b…
There is also a document download.eclipse.org/microprofil…
Anyway, back to the point.
Two, start learning
Sleepy, I will not demonstrate, directly look at the plug-in code ~ ~
1, RateLimiter
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
final String handle = rule.getHandle();
final RateLimiterHandle limiterHandle = GsonUtils.getInstance().fromJson(handle, RateLimiterHandle.class);
return redisRateLimiter.isAllowed(rule.getId(), limiterHandle.getReplenishRate(), limiterHandle.getBurstCapacity())
.flatMap(response -> {
if(! response.isAllowed()) { exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS); Object error = SoulResultWrap.error(SoulResultEnum.TOO_MANY_REQUESTS.getCode(), SoulResultEnum.TOO_MANY_REQUESTS.getMsg(),null);
return WebFluxResultUtils.result(exchange, error);
}
return chain.execute(exchange);
});
}
Copy the code
RedisRateLimiter#isAllowed indicates the method of limiting traffic
public Mono<RateLimiterResponse> isAllowed(final String id, final double replenishRate, final double burstCapacity) {
if (!this.initialized.get()) {
throw new IllegalStateException("RedisRateLimiter is not initialized");
}
List<String> keys = getKeys(id);
List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "", Instant.now().getEpochSecond() + ""."1");
Flux<List<Long>> resultFlux = Singleton.INST.get(ReactiveRedisTemplate.class).execute(this.script, keys, scriptArgs);
return resultFlux.onErrorResume(throwable -> Flux.just(Arrays.asList(1L, -1L)))
.reduce(new ArrayList<Long>(), (longs, l) -> {
longs.addAll(l);
return longs;
}).map(results -> {
boolean allowed = results.get(0) = =1L;
Long tokensLeft = results.get(1);
RateLimiterResponse rateLimiterResponse = new RateLimiterResponse(allowed, tokensLeft);
log.info("RateLimiter response:{}", rateLimiterResponse.toString());
return rateLimiterResponse;
}).doOnError(throwable -> log.error("Error determining if user allowed from redis:{}", throwable.getMessage()));
}
Copy the code
You can see that the Redis operation is in Reactive mode, the specific Lua script
private RedisScript<List<Long>> redisScript() {
DefaultRedisScript redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("/META-INF/scripts/request_rate_limiter.lua")));
redisScript.setResultType(List.class);
return redisScript;
}
Copy the code
In/meta-INF /scripts/request_rate_limiter. Lua, I can’t read it anyway.
2, Hystrix
Hystrix has not been updated for 4 years, RxJava does not have ProjectReactor fire, and Netfix officials have asked you to step up Resilience4J ~ _ ~
3, Sentinel
I can’t get away with that. I’ll give up.
4, Resilience4J
Resilience4j is a lightweight fault-tolerant framework designed for Java8 and functional programming, inspired by Netflix Hystrix. The framework simply uses Varr’s library, without introducing any other external dependencies. In contrast, Netflix Hystrix has a compile dependency on Archaius, which requires more external dependencies, such as Guava and Apache Commons Configuration.
Finally, the recommend an article to introduce Sentinel my.oschina.net/xiaominmin/…
Anyway, life is short, so with all the current limiting tools, choose Sentinel, it’s really energetic. I’m looking at Redis current limiting.