引言
分布式限流器处理两种情况: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 计数器方法,优化了实现分布式服务可用性。