💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
对外提供api 接口调用服务, 为防止某个用户请求过多导致服务器宕机,限制具体用户请求接口的QPS 自定义注解 ``` import java.lang.annotation.*; /** * 登录用户访问接口qps限制, 未登录用户这里不做限制 */ @Target({ ElementType.PARAMETER, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface UserRestrictAccess { /** 限制时间,单位是秒 */ long ttl() default 1; /** 限制时间内用户的访问次数 */ int userQps() default 1; } ``` 注解实现 ``` @Aspect @Component @Slf4j public class UserRestrictAccessAspect { @Autowired RedisService redisService; @Before("@annotation(userRestrictAccess)") public void doBefore(JoinPoint point, UserRestrictAccess userRestrictAccess) throws Throwable { try { doHandler(point, userRestrictAccess); } catch (BusinessException be) { throw be; } catch (Exception e) { log.error("UserRestrictAccessAspect {} ", e.getMessage()); } } private void doHandler(JoinPoint point, UserRestrictAccess userRestrictAccess) { //获取当前线程的访问对象 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); //获取访问路径 String requestURI = request.getRequestURI(); //获取用户token Long userId = SecurityUtils.getUserId(); // 登录的才需要做限制 if (userId == null) { return; } //存在redis中的key String key = BaseConstant.USER_RESTRICT_ACCESS_REDIS + ":pre_" + requestURI + ":" + userId; // 获取方法上的注解 int userQps = userRestrictAccess.userQps(); long ttl = userRestrictAccess.ttl(); //从redis中获取用户再限定时间内访问接口的次数 Integer value = (Integer) redisService.get(key); if (Objects.nonNull(value) && value >= userQps) { throw new BusinessException("您的操作过于频繁,请待会再试"); } if (Objects.isNull(value)) { //不存在key则设置初始值并且设置过期时间 redisService.setCacheObject(key, 1, ttl, TimeUnit.SECONDS); } else { // 存在则将访问次数 +1 redisService.redisTemplate.opsForValue().increment(key); } } } ```