tsurumure 1 year ago
parent
commit
528f4bdcb0

+ 23 - 0
src/main/java/com/backendsys/aspect/CurrentLimiting.java

@@ -0,0 +1,23 @@
+package com.backendsys.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CurrentLimiting {
+    /**
+     * 缓存key
+     */
+    String key() default "apiKey:";
+    /**
+     * 限流时间,单位秒
+     */
+    int time() default 10;
+    /**
+     * 限流次数
+     */
+    int count() default 3;
+}

+ 87 - 0
src/main/java/com/backendsys/aspect/CurrentLimitingAspect.java

@@ -0,0 +1,87 @@
+package com.backendsys.aspect;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Aspect
+@Component
+@RequiredArgsConstructor
+public class CurrentLimitingAspect {
+
+    private final RedisTemplate redisTemplate;
+
+    /**
+     * 带有注解的方法之前执行
+     */
+    @SuppressWarnings("unchecked")
+    @Before("@annotation(currentLimiting)")
+    public void doBefore(JoinPoint point, CurrentLimiting currentLimiting) throws Throwable {
+        int time = currentLimiting.time();
+        int count = currentLimiting.count();
+        // 将接口方法和用户IP构建Redis的key
+        String key = getCurrentLimitingKey(currentLimiting.key(), point);
+        // 未达到限流次数,自增
+        long value = redisTemplate.opsForValue().increment(key, 1);
+
+        if (value > count) {
+            log.error("接口限流,key:{},count:{},currentCount:{}", key, count, value);
+            throw new RuntimeException("访问过于频繁,请稍后再试!");
+        }
+
+        // 第一次请求设置过期时间
+        if(value == 1){
+            redisTemplate.expire(key, time, TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 组装 redis 的 key
+     */
+    private String getCurrentLimitingKey(String prefixKey,JoinPoint point) {
+        StringBuilder sb = new StringBuilder(prefixKey);
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+//        sb.append( Utils.getIpAddress(request) );
+
+        MethodSignature signature = (MethodSignature) point.getSignature();
+        Method method = signature.getMethod();
+        Class<?> targetClass = method.getDeclaringClass();
+        return sb.append("_")
+//                .append( targetClass.getName() )
+                .append("_").append(method.getName()).toString();
+    }
+
+    /**
+     * 获取ip地址
+     * @param request
+     * @return
+     */
+    private String getIpAddress(HttpServletRequest request) {
+        // 从请求头或代理头中获取真实IP地址
+        String ipAddress = request.getHeader("X-Forwarded-For");
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getRemoteAddr();
+        }
+        return ipAddress;
+    }
+
+}

+ 7 - 0
src/main/java/com/backendsys/controller/api/TestController.java

@@ -3,6 +3,7 @@ package com.backendsys.controller.api;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
 
 
+import com.backendsys.aspect.CurrentLimiting;
 import com.backendsys.aspect.QueuingPoll;
 import com.backendsys.aspect.QueuingPoll;
 import com.backendsys.entity.Tencent.TencentCos.UploadOriginDTO;
 import com.backendsys.entity.Tencent.TencentCos.UploadOriginDTO;
 import com.backendsys.service.SDKService.SDKTencent.SDKTencentCOSService;
 import com.backendsys.service.SDKService.SDKTencent.SDKTencentCOSService;
@@ -78,6 +79,12 @@ public class TestController {
 
 
 
 
 
 
+    @CurrentLimiting(count = 2, time = 10)
+    @GetMapping("testSemaphore")
+    public String testSemaphore() {
+        return "ok";
+    }
+
 //    @Autowired
 //    @Autowired
 //    private SysResourceService sysResourceService;
 //    private SysResourceService sysResourceService;
 //
 //

+ 8 - 8
src/main/java/com/backendsys/controller/api/Upload/UploadTencentCOSController.java

@@ -53,14 +53,14 @@ public class UploadTencentCOSController {
     private SDKTencentCOSService sdkTencentCOSService;
     private SDKTencentCOSService sdkTencentCOSService;
 
 
 
 
-//    /**
-//     * 权限:待定
-//     * 获得临时上传密钥 (用于前端单文件上传、分片上传)
-//     */
-//    @GetMapping("/api/upload/getTempCredentials")
-//    public Result getTempCredentials() {
-//        return Result.success(sdkTencentCOSService.getTempCredentials("*"));
-//    }
+    /**
+     * 权限:待定
+     * 获得临时上传密钥 (用于前端单文件上传、分片上传)
+     */
+    @GetMapping("/api/upload/getTempCredentials")
+    public Result getTempCredentials() {
+        return Result.success(sdkTencentCOSService.getTempCredentials("*"));
+    }
 
 
 //    /**
 //    /**
 //     * 权限:待定
 //     * 权限:待定

+ 2 - 1
src/main/java/com/backendsys/service/Med/MedMaterialServiceImpl.java

@@ -136,7 +136,8 @@ public class MedMaterialServiceImpl implements MedMaterialService {
     public TempCredentialsDTO getTempCredentials() {
     public TempCredentialsDTO getTempCredentials() {
         // [查询] 自身 UserId
         // [查询] 自身 UserId
         Long user_id = httpRequestAspect.getUserId();
         Long user_id = httpRequestAspect.getUserId();
-        return sdkTencentCOSService.getTempCredentials("materials/" + user_id + "/*");
+//        return sdkTencentCOSService.getTempCredentials("materials/" + user_id + "/*");
+        return sdkTencentCOSService.getTempCredentials("temp/*");
     }
     }
 
 
 }
 }

+ 2 - 0
src/main/resources/application-local.yml

@@ -93,10 +93,12 @@ tencent:
     secret-id-temp: AKIDVuCIAoKiuzyqV1hIo8HEJtKcm8NWXkx4
     secret-id-temp: AKIDVuCIAoKiuzyqV1hIo8HEJtKcm8NWXkx4
     secret-key-temp: 763nQwV0JPQDsLYeeaWL4atMhvynaGjy
     secret-key-temp: 763nQwV0JPQDsLYeeaWL4atMhvynaGjy
     # ------------------------------------------------------
     # ------------------------------------------------------
+
     region: ap-hongkong
     region: ap-hongkong
     bucket-name: storage-1320301544
     bucket-name: storage-1320301544
     # accessible-domain: https://storage-1320301544.cos.ap-hongkong.myqcloud.com
     # accessible-domain: https://storage-1320301544.cos.ap-hongkong.myqcloud.com
     accessible-domain: http://cos.daoguyujia.com
     accessible-domain: http://cos.daoguyujia.com
+
   ivh:
   ivh:
     empty-app-key: 283ca6dc9d4147debc60bf9fc3fbbe03         # 空数据账号 (我自己的子账号)
     empty-app-key: 283ca6dc9d4147debc60bf9fc3fbbe03         # 空数据账号 (我自己的子账号)
     empty-access-token: eea44503a2f64c119fb0acd2006dacb0
     empty-access-token: eea44503a2f64c119fb0acd2006dacb0