简单的针对某个接口进行限流,如果需要整体限流的话还是建议在网关上面或者服务器上面动手
Controller:
@LimitRequest(count = 1,time = 60 * 1000 * 2)
@PostMapping("limit")
public String getLimitResult() {
return "ok";
}
Annotation:
@Retention(RetentionPolicy.RUNTIME) // 运行时
@Target({ElementType.TYPE, ElementType.METHOD}) // 可以被用在类及方法上
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public @interface LimitRequest {
/**
* @return 允许的请求次数,默认 MAX_VALUE
*/
int count() default Integer.MAX_VALUE;
/**
* @return 时间段,单位为毫秒数(和redis统一),默认 1分钟
*/
int time() default 60 * 1000;
/**
* @return 触发限流之后抛出的异常信息
*/
String meg() default "登记太频繁,请2分钟之后再次登记!";
}
AOP:
@Slf4j
@Aspect
@Component
@Order(1)
public class LimitRequestAop {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Around("@annotation(limitRequest)")
public Object doAround(ProceedingJoinPoint joinPoint, LimitRequest limitRequest) throws Throwable {
// 获取当前请求对象
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
boolean flag = true;
HttpServletRequest request = attributes.getRequest();
// String ipAddr = request.getRemoteAddr(); //根据自己需求来确定下面拼redis key值的时候要不要拼上客户端的ip
// logger.info("ip" + ipAddr);
String uri = request.getRequestURI();
if (limitRequest != null) {
flag = validRequestCount( uri.replace("/", "_"), limitRequest.count(), limitRequest.time());
}
if (flag) {
return joinPoint.proceed();
}
throw new RuntimeException(limitRequest.meg());
}
/**
* 判断某一个ip请求接口的次数是否超过限制
*
* @param uri 接口路径
* @param limitCount 限流大小
* @param timeOut 判断限流的时间
* @return true 未限流 false 限流
*/
private boolean validRequestCount(String uri, int limitCount, long timeOut) {
try {
// /api/queryInfo
String redisKey = "req_limit_".concat(uri);
long count = redisTemplate.opsForValue().increment(redisKey, 1);
if (count == 1) {
redisTemplate.expire(redisKey, timeOut, TimeUnit.MILLISECONDS);
}
if (count > limitCount) {
return false;
}
} catch (Exception e) {
return false;
}
return true;
}
}
标签:count,return,String,redis,接口,限流,limitRequest From: https://www.cnblogs.com/ji-firee/p/17719510.html