1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| @Component @Scope @Aspect public class RateLimitAop {
@Autowired private RedissonClient redissonClient;
@Pointcut("@annotation(com.data.estimated.limiter.RateLimitAspect)") public void serviceLimit() {
}
@Around("serviceLimit()") public Object around(ProceedingJoinPoint joinPoint) { ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()); HttpServletRequest request = servletRequestAttributes.getRequest(); HttpServletResponse response = servletRequestAttributes.getResponse(); StringBuffer buffer = new StringBuffer(); String url = request.getRequestURI(); buffer.append(StrUtil.replace(url,"/","_")); buffer.append("_"); buffer.append(IPUtil.getIpAddr(request)); RRateLimiter rRateLimiter = getRRateLimiter(joinPoint,buffer.toString()); boolean flag = rRateLimiter.tryAcquire(); Object obj = null; try { if (flag) { obj = joinPoint.proceed(); }else{ outRateLimiterMsg(response,new JSONObject(BaseResult.LIMIT_FAIL()).toString()); } } catch (Throwable e) { e.printStackTrace(); outRateLimiterMsg(response,new JSONObject(BaseResult.FAIL()).toString()); } return obj; }
private RRateLimiter getRRateLimiter(ProceedingJoinPoint joinPoint,String limitKey){ RateLimitAspect rateLimit = getRateLimitAspect(joinPoint); long count = rateLimit.count(); long time = rateLimit.time(); RRateLimiter rRateLimiter = redissonClient.getRateLimiter(StrUtil.isBlank(rateLimit.key()) ? limitKey : rateLimit.key()); if(rRateLimiter.isExists()){ RateLimiterConfig rateLimiterConfig = rRateLimiter.getConfig(); long rateInterval = rateLimiterConfig.getRateInterval(); long rate = rateLimiterConfig.getRate(); if(time != rateInterval || rate != count){ rRateLimiter.delete(); rRateLimiter.trySetRate(RateType.OVERALL, count ,time , RateIntervalUnit.SECONDS); } } rRateLimiter.trySetRate(RateType.OVERALL, count ,time , RateIntervalUnit.SECONDS); return rRateLimiter; }
private RateLimitAspect getRateLimitAspect(ProceedingJoinPoint joinPoint){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); RateLimitAspect rateLimit = method.getAnnotation(RateLimitAspect.class); return rateLimit; }
private void outRateLimiterMsg(HttpServletResponse response,String message){ PrintWriter writer = null; try { response.reset(); response.setCharacterEncoding("utf-8"); response.setHeader("content-type", "application/json;charset=utf-8"); response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Headers", "X-Requested-With"); response.addHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"); writer = response.getWriter(); writer.write(message); } catch (Exception e) { e.printStackTrace(); }finally { IoUtil.close(writer); } } }
|