限流
一、常见限流算法
计数器算法:对于每次服务调用,可以通过AtomicLong#incrementAndGet()方法来给计数器加1并返回最新值,通过这个最新值和阈值进行比较。
漏洞算法:可以准备一个队列,用来保存请求,另外通过一个线程池(ScheduledExecutorService)来定期从队列中获取请求并执行,可以一次性获取多个并发执行。
令牌桶算法:可以准备一个队列,用来保存令牌,另外通过一个线程池定期生成令牌放到队列中,每来一个请求,就从队列中获取一个令牌,并继续执行。
实现方式
单机模式:Semaphore 、Google Guava RateLimiter
分布式:
redis(令牌桶算法)
一个生产者线程不断往redis添加令牌(写),其他请求线程每次请求读redis获取令牌,这样会有很大的性能损耗;
延迟放令牌的操作:此刻应填充令牌数 = min((令牌桶剩余令牌数 + 当前时间与上一次令牌生成时间间隔 * 令牌生成速度), 令牌总容量)
Spring Cloud Gateway:RequestRateLimiterGatewayFilterFactory这个类,适用Redis和lua脚本实现了令牌桶的方式
Spring Cloud Alibaba Sentinel:具有可配置页面、可整合gateway使用