生产环境下可以解决的问题:
1.短信验证码请求评率限制(防止抓包短信轰炸)
2.热点数据请求评率限制(防止数据库爆炸)
1.创建自定义注解

package com.bysk.base.annotation; import java.lang.annotation.*; /** * @author: zhangyb * @date: 2020/11/11 13:58 * @Description: 防止表单重复提交 使用这个注解必须要返回Result类型 * @UpdateUser : zhangyb * @UpdateDate :2020/11/11 13:58 * @UpdateRemark: */ @Target({ ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FormSubmitLimit { /** * @author: zhangyb * @date: 2020/11/11 14:00 * @Description: 默认两秒 * @UpdateUser : zhangyb * @UpdateDate :2020/11/11 14:00 * @UpdateRemark: */ long limitTime() default 2L; /** * @author: zhangyb * @date: 2020/11/11 14:03 * @Description: 是否需要登录,默认需要登录 * @UpdateUser : zhangyb * @UpdateDate :2020/11/11 14:03 * @UpdateRemark: */ boolean isLogin() default true; }
2.AOP实现之定义注解

package com.bysk.admin.common.filter; import cn.hutool.extra.servlet.ServletUtil; import com.alibaba.fastjson.JSONObject; import com.bysk.base.annotation.FormSubmitLimit; import com.bysk.base.enums.MsgEnum; import com.bysk.base.model.Result; import com.bysk.base.util.MD5Utils; import com.bysk.base.util.RedisUtils; import com.bysk.base.util.WebUtils; import lombok.SneakyThrows; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * @author: zhangyb * @date: 2020/11/11 14:02 * @Description: 防止表单重复提交的请求 使用此注解返回类型必须是R Result * @UpdateUser : zhangyb * @UpdateDate :2020/11/11 14:02 * @UpdateRemark: */ @Aspect @Component public class FormSubmitAspect { @Autowired RedisUtils redisUtils; @Around("@annotation(formSubmitLimit)") @SneakyThrows public Object doBefore(ProceedingJoinPoint point, FormSubmitLimit formSubmitLimit) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String requestURI = request.getRequestURI(); if (formSubmitLimit.isLogin()){ //如果需要登录redis存储规则 userid<->请求url_method Object o = redisUtils.get(WebUtils.getUser().getId() + ""); if (o!=null){ return JSONObject.toJSONString(Result.fail(MsgEnum.OPR_FAST)); } try { redisUtils.set(WebUtils.getUser().getId()+"",requestURI,formSubmitLimit.limitTime()); } catch (NullPointerException e) { return Result.fail(); } }else{ //客户端IP String clientIP = ServletUtil.getClientIP(request); //客户端请求头的userAgent String header = request.getHeader("User-Agent"); //MD5加密后的值 String noLoignKey = MD5Utils.encryptBasedDes(clientIP + header); Object o = redisUtils.get(noLoignKey); if (o!=null){ return Result.fail(MsgEnum.OPR_FAST); } //不需要登录redis存储规则 ip+user_agent(MD5)<-> 请求url_mthod redisUtils.set(noLoignKey,requestURI,formSubmitLimit.limitTime()); } return point.proceed(); } }