@RestController
public class GuavaRate {
@ZRateLimiter(rate = 5,timeOut = 100)
@RequestMapping("/find2")
public void tryAcquire(){
}
}
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ZRateLimiter {
//往令牌桶放入令牌的速率
double rate();
//获取令牌桶的超时时间
long timeOut() default 0;
}
@Aspect
@Component
public class RateLimiterAspect {
@Autowired
private HttpServletResponse response;
private RateLimiter rateLimiter=RateLimiter.create(50);
// @Pointcut("execution(public * com.aop.demo.aop.*.*(..))")
@Pointcut("@annotation(com.aop.demo.GUAVA.ZRateLimiter)")
public void pointcut(){}
@Around("pointcut()")
public Object RateLimiter2(ProceedingJoinPoint joinPoint)throws Throwable{
//通过切点获取签名
MethodSignature signature= (MethodSignature)joinPoint.getSignature();
ZRateLimiter zRateLimiter
= signature.getMethod().getDeclaredAnnotation(ZRateLimiter.class);
if(zRateLimiter==null){
//没有加限流的注解的话,就直接正常执行业逻辑,不参与接口的限流保护
return joinPoint.proceed();
}
double rate = zRateLimiter.rate();//获取注解上的参数
long timeOut = zRateLimiter.timeOut();//获取令牌等待时间
rateLimiter.setRate(rate);
boolean tryAcquire = rateLimiter.tryAcquire(timeOut, TimeUnit.MILLISECONDS);
if(!tryAcquire){
System.out.println("服务繁忙,请稍后再试");
return "服务繁忙,请稍后再试";
}
//获取到令牌
System.out.println("success");
//执行业务代码
return joinPoint.proceed();
}
}
//解释Guava限流包下的一个限流的算法
RateLimiter rateLimiter=RateLimiter.create(5);//create(5)表示的是一秒发出5个令牌,每200毫秒一个令牌
System.out.println(rateLimiter.acquire(1));
System.out.println(rateLimiter.acquire(1));
System.out.println(rateLimiter.acquire(1));
System.out.println(rateLimiter.acquire(1));
//执行的结果是
0.0
0.198121
0.192586
0.198563
RateLimiter rateLimiter=RateLimiter.create(5);//create(5)表示的是一秒发出5个令牌,每200毫秒一个令牌
//突然接受一个大量的请求
System.out.println(rateLimiter.acquire(100));
System.out.println(rateLimiter.acquire(1));
System.out.println(rateLimiter.acquire(1));
System.out.println(rateLimiter.acquire(1));
//执行的结果
0.0
19.99783
0.192275
0.197414
//解释。第一次执行100个请求的时候,需要时间为0,但是第二次限流保护的时候,执行的时间为约20秒,就是所有的时间都累 计到第二次限流保护