赞
踩
测试controller
package com.example.redislimiter.redislimiter.controller; import com.example.redislimiter.redislimiter.aspectj.Limiter; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author :xusy * @date Created in 2022/9/7 18:20 */ @RestController public class UserController { @Limiter(frequency = 3,limitTime = 30) //每30秒限制3次请求 @GetMapping("/user/getUser") public String getUser(){ return "xsy"; } }
自定义注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Limiter { /** * 限制时间 (单位:秒) * @return */ int limitTime() default 1; /** * 接口访问频率 * @return */ int frequency() default 10; }
aspect拦截类
package com.example.redislimiter.redislimiter.aspectj; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.util.ObjectUtils; import javax.servlet.http.HttpServletRequest; import java.util.concurrent.TimeUnit; /** * @author :xusy * @date Created in 2022/9/7 16:20 */ @Configuration @Aspect public class LimiterAspect { Logger log = LoggerFactory.getLogger(LimiterAspect.class); @Autowired private HttpServletRequest request; @Autowired private RedisTemplate redisTemplate; private static final String limitKey = "limitKey_"; private static final String message = "请求次数过多,请稍后再试..."; @Pointcut("@annotation(com.example.redislimiter.redislimiter.aspectj.Limiter)") public void point(){ } @Around("point()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Limiter annotation = signature.getMethod().getAnnotation(Limiter.class); int limitTime = annotation.limitTime();//限制时间 int frequency = annotation.frequency();//请求频率 String key = getIP() + getUri(); Integer time = (Integer) redisTemplate.opsForValue().get(limitKey + key); log.info("key:{}",key); if(ObjectUtils.isEmpty(time)) { redisTemplate.opsForValue().set(limitKey + key,1,limitTime, TimeUnit.SECONDS); return joinPoint.proceed(); } else { if(time >= frequency) { throw new RuntimeException(message); } else { redisTemplate.opsForValue().set(limitKey + key,time+1,0); return joinPoint.proceed(); } } } /** * 获取访问者ip地址 * @param * @return */ private String getIP() { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } /** * 获取访问者uri路劲 * @param * @return */ private String getUri(){ return request.getRequestURI(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。