频率限制1

This commit is contained in:
GYJ
2025-03-23 16:48:07 +08:00
parent 82ce8de138
commit 7a4a57c4ef
4 changed files with 25 additions and 27 deletions

View File

@@ -13,7 +13,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Limiting { public @interface Limiting {
// 默认每秒放入桶中的token // 默认每秒放入桶中的token
double limitNum() default 20; double limitNum() default 10;
String name() default "";
} }

View File

@@ -10,7 +10,10 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -30,32 +33,29 @@ public class RateLimitAspect {
@Around("serviceLimit()") @Around("serviceLimit()")
public Object around(ProceedingJoinPoint point) throws Throwable { public Object around(ProceedingJoinPoint point) throws Throwable {
//获取拦截的方法名 // 获取当前请求
Signature sig = point.getSignature(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取拦截的方法名 HttpServletRequest request = attributes.getRequest();
MethodSignature msig = (MethodSignature) sig; // 获取请求的 IP 地址
//返回被织入增加处理目标对象 String ip = request.getRemoteAddr();
Object target = point.getTarget();
//为了获取注解信息
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
//获取注解信息
Limiting annotation = currentMethod.getAnnotation(Limiting.class);
//获取注解每秒加入桶中的token
double limitNum = annotation.limitNum();
// 注解所在方法名区分不同的限流策略
String functionName = msig.getName();
if (RATE_LIMITER.containsKey(functionName)) { // 获取方法上的 @AccessLimit 注解
rateLimiter = RATE_LIMITER.get(functionName); MethodSignature signature = (MethodSignature) point.getSignature();
} else { Method method = signature.getMethod();
RATE_LIMITER.put(functionName, RateLimiter.create(limitNum)); Limiting accessLimit = method.getAnnotation(Limiting.class);
rateLimiter = RATE_LIMITER.get(functionName); double permitsPerSecond = accessLimit.limitNum();
}
// 获取或创建该 IP 对应的 RateLimiter
RateLimiter rateLimiter = RATE_LIMITER.computeIfAbsent(ip, k -> RateLimiter.create(permitsPerSecond));
// 尝试获取许可
if (rateLimiter.tryAcquire()) { if (rateLimiter.tryAcquire()) {
// 成功获取许可,继续执行方法
return point.proceed(); return point.proceed();
} else { } else {
log.info("超过限流限制, {}", functionName); // 未获取到许可,抛出异常或返回错误信息
throw new RuntimeException("服务器繁忙,请稍后再试。"); log.info("IP: {} 请求方法: {} 超过访问频率限制", ip, method.getName());
throw new RuntimeException("访问频率过高,请稍后再试");
} }
} }
} }

View File

@@ -23,7 +23,7 @@ public class AppCourseCollectController extends AbstractController {
@Login @Login
@PostMapping("/insertCourseCollect") @PostMapping("/insertCourseCollect")
@ApiOperation("app收藏短剧信息") @ApiOperation("app收藏短剧信息")
@Limiting(name = "AppCourseCollectController-insertCourseCollect", limitNum = 25) @Limiting
public Result insertCourseCollect(@RequestBody CourseCollect courseCollect, @RequestAttribute("userId") Long userId) { public Result insertCourseCollect(@RequestBody CourseCollect courseCollect, @RequestAttribute("userId") Long userId) {
courseCollect.setUserId(userId); courseCollect.setUserId(userId);
return courseCollectService.insertCourseCollect(courseCollect); return courseCollectService.insertCourseCollect(courseCollect);

View File

@@ -39,7 +39,7 @@ public class AppOrdersController extends AbstractController {
@GetMapping("/insertCourseOrders") @GetMapping("/insertCourseOrders")
@ApiOperation("生成商品订单") @ApiOperation("生成商品订单")
@Debounce(interval = 20000, value = "#userId") @Debounce(interval = 20000, value = "#userId")
@Limiting(name = "AppOrdersController-insertCourseOrders", limitNum = 60) @Limiting
public Result insertCourseOrders(Long courseId,Long courseDetailsId, @RequestAttribute("userId") Long userId) { public Result insertCourseOrders(Long courseId,Long courseDetailsId, @RequestAttribute("userId") Long userId) {
return ordersService.insertCourseOrders(courseId, courseDetailsId,userId); return ordersService.insertCourseOrders(courseId, courseDetailsId,userId);
} }