浏览代码

api rate limit

deason 1 年之前
父节点
当前提交
46d2287cb3

+ 5 - 0
src/main/java/com/qmth/exam/reserve/bean/Constants.java

@@ -7,6 +7,11 @@ public interface Constants {
 
     String SYSTEM_BUSY = "当前请求繁忙,请稍后再试!";
 
+    /**
+     * 接口限流规则:每秒/N次
+     */
+    String API_LIMIT_EXPRESSION = "1000/1s";
+
     /**
      * 分类层级
      */

+ 17 - 0
src/main/java/com/qmth/exam/reserve/controller/student/StudentApplyController.java

@@ -2,6 +2,10 @@ package com.qmth.exam.reserve.controller.student;
 
 import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.api.exception.DefaultExceptionEnum;
+import com.qmth.boot.core.rateLimit.entity.RateLimitRule;
+import com.qmth.boot.core.rateLimit.service.RateLimitService;
+import com.qmth.exam.reserve.bean.Constants;
 import com.qmth.exam.reserve.bean.RichTextBean;
 import com.qmth.exam.reserve.bean.apply.ApplyTimePeriodResult;
 import com.qmth.exam.reserve.bean.apply.ApplyVO;
@@ -32,10 +36,18 @@ public class StudentApplyController extends BaseController {
     @Autowired
     private ExamReserveService examReserveService;
 
+    @Autowired
+    private RateLimitService rateLimitService;
+
     @ApiOperation(value = "保存考生预约结果")
     @PostMapping(value = "/apply/save")
     public void save(@ApiParam("考点ID") @RequestParam Long examSiteId,
                      @ApiParam("预约时段ID") @RequestParam Long timePeriodId) {
+        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
+        if (!rateLimitService.getRateLimiter("apply", null, limitRule).acquire()) {
+            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.SYSTEM_BUSY);
+        }
+
         examReserveService.saveStudentApply(curLoginStudent(), examSiteId, timePeriodId);
     }
 
@@ -43,6 +55,11 @@ public class StudentApplyController extends BaseController {
     @PostMapping(value = "/apply/cancel")
     public void cancel(@ApiParam("考点ID") @RequestParam Long examSiteId,
                        @ApiParam("预约时段ID") @RequestParam Long timePeriodId) {
+        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
+        if (!rateLimitService.getRateLimiter("cancelApply", null, limitRule).acquire()) {
+            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.SYSTEM_BUSY);
+        }
+
         examReserveService.cancelStudentApply(curLoginStudent(), examSiteId, timePeriodId);
     }
 

+ 19 - 9
src/main/java/com/qmth/exam/reserve/controller/student/StudentLoginController.java

@@ -1,23 +1,25 @@
 package com.qmth.exam.reserve.controller.student;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
 import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.api.exception.DefaultExceptionEnum;
+import com.qmth.boot.core.rateLimit.entity.RateLimitRule;
+import com.qmth.boot.core.rateLimit.service.RateLimitService;
+import com.qmth.exam.reserve.bean.Constants;
 import com.qmth.exam.reserve.bean.login.LoginReq;
 import com.qmth.exam.reserve.bean.login.LoginUser;
 import com.qmth.exam.reserve.bean.login.WechatLoginReq;
 import com.qmth.exam.reserve.controller.BaseController;
 import com.qmth.exam.reserve.service.AuthService;
-
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 @RestController
 @Api(tags = "【考生端】考生登录相关接口")
@@ -30,9 +32,17 @@ public class StudentLoginController extends BaseController {
     @Autowired
     private AuthService authService;
 
+    @Autowired
+    private RateLimitService rateLimitService;
+
     @ApiOperation(value = "考生登录(账号)")
     @PostMapping(value = "/login")
     public LoginUser login(@RequestBody LoginReq req) {
+        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
+        if (!rateLimitService.getRateLimiter("login", null, limitRule).acquire()) {
+            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.SYSTEM_BUSY);
+        }
+
         return authService.studentLogin(req);
     }