From 7a4a57c4efc1440cd69f8eb07bbb62d03c7d4963 Mon Sep 17 00:00:00 2001 From: GYJ <1157756119@qq.com> Date: Sun, 23 Mar 2025 16:48:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=91=E7=8E=87=E9=99=90=E5=88=B61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sqx/common/annotation/Limiting.java | 4 +- .../sqx/common/aspect/RateLimitAspect.java | 44 +++++++++---------- .../app/AppCourseCollectController.java | 2 +- .../controller/app/AppOrdersController.java | 2 +- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/sqx/common/annotation/Limiting.java b/src/main/java/com/sqx/common/annotation/Limiting.java index 1a2db1d4..7bfe978e 100644 --- a/src/main/java/com/sqx/common/annotation/Limiting.java +++ b/src/main/java/com/sqx/common/annotation/Limiting.java @@ -13,7 +13,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface Limiting { // 默认每秒放入桶中的token - double limitNum() default 20; - - String name() default ""; + double limitNum() default 10; } diff --git a/src/main/java/com/sqx/common/aspect/RateLimitAspect.java b/src/main/java/com/sqx/common/aspect/RateLimitAspect.java index 7b6d94a7..5e0b2292 100644 --- a/src/main/java/com/sqx/common/aspect/RateLimitAspect.java +++ b/src/main/java/com/sqx/common/aspect/RateLimitAspect.java @@ -10,7 +10,10 @@ import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; 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.util.concurrent.ConcurrentHashMap; @@ -30,32 +33,29 @@ public class RateLimitAspect { @Around("serviceLimit()") public Object around(ProceedingJoinPoint point) throws Throwable { - //获取拦截的方法名 - Signature sig = point.getSignature(); - //获取拦截的方法名 - MethodSignature msig = (MethodSignature) sig; - //返回被织入增加处理目标对象 - 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(); + // 获取当前请求 + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + // 获取请求的 IP 地址 + String ip = request.getRemoteAddr(); - if (RATE_LIMITER.containsKey(functionName)) { - rateLimiter = RATE_LIMITER.get(functionName); - } else { - RATE_LIMITER.put(functionName, RateLimiter.create(limitNum)); - rateLimiter = RATE_LIMITER.get(functionName); - } + // 获取方法上的 @AccessLimit 注解 + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Limiting accessLimit = method.getAnnotation(Limiting.class); + double permitsPerSecond = accessLimit.limitNum(); + + // 获取或创建该 IP 对应的 RateLimiter + RateLimiter rateLimiter = RATE_LIMITER.computeIfAbsent(ip, k -> RateLimiter.create(permitsPerSecond)); + + // 尝试获取许可 if (rateLimiter.tryAcquire()) { + // 成功获取许可,继续执行方法 return point.proceed(); } else { - log.info("超过限流限制, {}", functionName); - throw new RuntimeException("服务器繁忙,请稍后再试。"); + // 未获取到许可,抛出异常或返回错误信息 + log.info("IP: {} 请求方法: {} 超过访问频率限制", ip, method.getName()); + throw new RuntimeException("访问频率过高,请稍后再试"); } } } diff --git a/src/main/java/com/sqx/modules/course/controller/app/AppCourseCollectController.java b/src/main/java/com/sqx/modules/course/controller/app/AppCourseCollectController.java index d849f42e..f2ea1d95 100644 --- a/src/main/java/com/sqx/modules/course/controller/app/AppCourseCollectController.java +++ b/src/main/java/com/sqx/modules/course/controller/app/AppCourseCollectController.java @@ -23,7 +23,7 @@ public class AppCourseCollectController extends AbstractController { @Login @PostMapping("/insertCourseCollect") @ApiOperation("app收藏短剧信息") - @Limiting(name = "AppCourseCollectController-insertCourseCollect", limitNum = 25) + @Limiting public Result insertCourseCollect(@RequestBody CourseCollect courseCollect, @RequestAttribute("userId") Long userId) { courseCollect.setUserId(userId); return courseCollectService.insertCourseCollect(courseCollect); diff --git a/src/main/java/com/sqx/modules/orders/controller/app/AppOrdersController.java b/src/main/java/com/sqx/modules/orders/controller/app/AppOrdersController.java index 2d677709..c9139697 100644 --- a/src/main/java/com/sqx/modules/orders/controller/app/AppOrdersController.java +++ b/src/main/java/com/sqx/modules/orders/controller/app/AppOrdersController.java @@ -39,7 +39,7 @@ public class AppOrdersController extends AbstractController { @GetMapping("/insertCourseOrders") @ApiOperation("生成商品订单") @Debounce(interval = 20000, value = "#userId") - @Limiting(name = "AppOrdersController-insertCourseOrders", limitNum = 60) + @Limiting public Result insertCourseOrders(Long courseId,Long courseDetailsId, @RequestAttribute("userId") Long userId) { return ordersService.insertCourseOrders(courseId, courseDetailsId,userId); }