package cn.exrick.xboot.core.common.limit; import cn.exrick.xboot.core.common.constant.CommonConstant; import com.google.common.util.concurrent.RateLimiter; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RRateLimiter; import org.redisson.api.RateIntervalUnit; import org.redisson.api.RateType; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * 令牌桶算法限流 * @author Exrick */ @Slf4j @Component public class RedisRaterLimiter { @Autowired private RedissonClient redisson; private RateLimiter guavaRateLimiter = RateLimiter.create(Double.MAX_VALUE); /** * 基于Redis令牌桶算法 * @param name 限流标识(限流点) * @param rate 限制的数量 速率 * @param rateInterval 单位时间内(毫秒) * @return */ public Boolean acquireByRedis(String name, Long rate, Long rateInterval) { boolean getToken; try { RRateLimiter rateLimiter = redisson.getRateLimiter(CommonConstant.LIMIT_PRE + name); rateLimiter.trySetRate(RateType.OVERALL, rate, rateInterval, RateIntervalUnit.MILLISECONDS); getToken = rateLimiter.tryAcquire(); rateLimiter.expireAsync(rateInterval * 2, TimeUnit.MILLISECONDS); } catch (Exception e) { getToken = true; } return getToken; } /** * 基于内存令牌桶算法 * @param permitsPerSecond 1秒内限制的数量(QPS) * @return */ public Boolean acquireByGuava(Double permitsPerSecond) { guavaRateLimiter.setRate(permitsPerSecond); boolean getToken = guavaRateLimiter.tryAcquire(); return getToken; } }