限流可以在網關這一層做,比如Nginx、Openresty、kong、zuul、Spring Cloud Gateway等;也可以在應用層通過Aop這種方式去做限流。
一些限流元件,包括Redisson的令牌桶限流,Guava的RateLimiter(用戶端限流)。Hystrix是用戶端限流(參考彗安金科Java面試(部分) 或直接參考熔斷器Hystrix 或JavaGuide—Java面試指北—高性能:負載均衡的常見算法有哪些?)。
網關層限流
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLkVjN2ImZxM2MzQzY0I2NhFzNhRzMkljZ4MmMmJTNjNzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
1
網關層限流:gateway的限流基于Redis+Lua腳本1 2 :
Redisson分布式限流器RRateLimiter原了解析
單機限流:可Hystrix用線程池或Semaphore限流:
例1:深入 Hystrix 線程池隔離與接口限流
執行個體2:
RedisHystrixCommand.java :
public class RedisHystrixCommand<T> extends HystrixCommand<T> {
private static final Logger logger = new Logger("Hystrix");
private Callable<T> callable;
private T defaultResult;
private String opName;
/**
* constructor.
*/
public RedisHystrixCommand(String keyName, Callable<T> callable, T defaultResult,
String opName) {
// default timeout=1s, fallback when 50% or 20 requests in 10 seconds fail
super(Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(keyName))
.andCommandKey(HystrixCommandKey.Factory.asKey(keyName))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)
.withCircuitBreakerEnabled(true)));
this.callable = callable;
this.defaultResult = defaultResult;
this.opName = opName;
}
@Override
protected T run() throws Exception {
return callable.call();
}
@Override
protected T getFallback() {
logger.error("RedisCache {} fallback since executionTimeout, return {}",
opName, defaultResult);
return defaultResult;
}
}
RedisHelper.java:
public Long sadd(String key, String member) {
return new RedisHystrixCommand<>(getCommandKey(), () ->
getRedisClient().handle(redis -> redis.sadd(key, member))
.orElse(0L), 0L, "sadd").execute();
}
- 我司用了 6 年的 Redis 分布式限流器,可以說是非常厲害了! ↩︎ ↩︎
- Spring Cloud Gateway 之限流篇 ↩︎