redis 分布式限流器 spingboot + redisson

924 阅读1分钟

引言

分布式限流器处理两种情况:1.单机或者分布式情况下的缓存击穿;2.接口限制调用次数。限流器 RateLimter 的原理是:调用接口前指定令牌个数,限流器每秒会产生指定个数的令牌放入令牌桶,调用接口需要去令牌桶里面拿令牌。

RateLimiter 限流器

基于《redis 分布式缓存 springboot + redisson》中对 redisson 的依赖引入和初始化,使用 redissonClient.getRateLimiter 获取 rateLimter,使用 rateLimiter.trySetRate 设置令牌,使用 rateLimter.tryAcquire 获取一个令牌。

@Service
public class RateLimiterService {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(RateLimiterService.class);
 
    @Autowired
    private RedissonClient redisson;
 
    public void sendMsg(String phone) {
        if (StringUtils.isNotBlank(phone)) {
            RRateLimiter rateLimiter =
                    redisson.getRateLimiter(Constant.REDISSON_RATE_LIMITER + phone);
            //每10秒产生1个令牌
            rateLimiter.trySetRate(RateType.OVERALL, 1, 10,
                    RateIntervalUnit.SECONDS);
 
            if (rateLimiter.tryAcquire(1)) {
                LOGGER.info("向手机:{}发送短信", phone);
            }
        }
    }
}

RAtomicLong 计数器

使用 redissonClient.getAtomicLong 获取计数器,接口具体方法如下:

public interface RAtomicLong extends RExpirable, RAtomicLongAsync {
 
    long get();                  //获取数值
 
    long getAndIncrement();      //数值加1,返回原值
    long incrementAndGet();      //加一后返回数最新值
    long getAndAdd(long var1);   //加var1,返回原值
    long addAndGet(long var1);   //加var1后返回最新值
 
    long getAndDelete();         //获取数值后删除数据
 
    long getAndDecrement();      //数值减一,返回原值
    long decrementAndGet();      //数值减一,返回最新值
 
    void set(long var1);                         //设置值为var1
    long getAndSet(long var1);                   //设置值为var1,返回原值
    boolean compareAndSet(long var1, long var3); //原子替换值为var3
}

总结

综上,在限流、限次的业务场景中,redisson 提供了 RateLimiter 限流器和 RAtomicLong 计数器方法,优化了实现分布式服务可用性。