Redis限流-redission
定义限流类型
public enum LimitType {
DEFAULT,
IP,
TOKEN_BUCKET,
}
定义限流自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
int limitValue() default 10;
int maxConcurrentRequests() default 2;
String key() default "";
LimitType limitType() default LimitType.DEFAULT;
String message() default "前方拥挤,请稍后再试";
boolean failFast() default true;
}
使用Spring AOP进行前置拦截
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class RateLimitAspect {
private final RedisRateLimiter redisRateLimiter;
private ExpressionParser parser = new SpelExpressionParser();
private DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
@Around("@annotation(rateLimit)")
public Object limit(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
String methodName = method.getName();
String uniqueKey = getUniqueKey(methodName, joinPoint, rateLimit);
log.info("方法:{} 限流key:{} 限流开始", methodName, uniqueKey);
boolean acquired = redisRateLimiter.acquireForRedisson(methodName, rateLimit, uniqueKey);
if (!acquired) {
log.error("方法:{} 触发限流,限流key:{}", methodName, uniqueKey);
throw new RateLimitExceededException(rateLimit.message());
}
try {
return joinPoint.proceed();
} finally {
redisRateLimiter.release(methodName, uniqueKey);
log.info("方法:{} 限流key:{} 限流正常结束", methodName, uniqueKey);
}
}
private String