为什么要限流
在电商中经常有秒杀的场景,就是在某一瞬间会有高并发的产生。每一个API接口都有自己的访问上限,当接口的访问频率超过其承受范围时,为防止雪崩效应可以采用限流的方式给接口安上保险丝,保证接口的可用性。
具体样例
我这里先自定义作用于方法上的限流注解,然后用aop切面去拦截包含有自定义限流注解的接口,再结合谷歌开源工具包com.google.concurrent.RateLimiter类(令牌桶算法)来实现限流。
自定义RequestLimit注解
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestLimit {
}
aop切面配置
@Component
@Scope
@Aspect
@Slf4j
public class LimitAspect {
//每秒只发出指定个令牌(这里方便测试用1个),此处是单进程服务的限流,内部采用令牌捅算法实现
private static RateLimiter rateLimiter = RateLimiter.create(1.0);
//Controller层切点 限流
@Pointcut("@annotation(com.chenyulian.aop.RequestLimit)")
public void requestAspect() {
}
@Around("requestAspect()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Boolean flag = rateLimiter.tryAcquir