超级悠悠
高性能程序定制、UI定制
576881

访问

1

评论

19

动态

2059

运行

来过
设计群: 70888820
位置: luzhou·sichuan

- 今日签到 -

今日暂无签到

首页破碎代码SpringBoot接口频率限制(不限制IP)

SpringBoot接口频率限制(不限制IP)

评论 0/访问 3487/分类: 破碎代码/发布时间:

依赖

<dependency>
 	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

代码

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FrequencyLimit {
    // 频率限制时间,默认值为1分钟(60,000 毫秒)
    long time() default 60000L;
    // 频率限制数量,默认值为 5 次
    int frequency() default 5;
}
@Aspect
@Component
public class FrequencyLimitAspect {
    private static final Map<String, List<Long>> ACCESS_RECORD = new ConcurrentHashMap<>();
    @Around("@annotation(limit)")
    public Object around(ProceedingJoinPoint joinPoint, FrequencyLimit limit) throws Throwable {
        //获取请求方法的名称和参数列表
        String methodName = joinPoint.getSignature().toLongString();
        Object[] args = joinPoint.getArgs();
        //获取限制时间和数量
        long time = limit.time();
        int frequency = limit.frequency();
        //检查是否已经超过频率限制
        if (!checkAccessFrequency(methodName, time, frequency)) {
            throw new RuntimeException("请求太频繁,请稍后再试");
        }
        //执行目标方法并返回结果
        return joinPoint.proceed(args);
    }
    /**
     * 检查访问频率是否超限
     *
     * @param methodName 请求方法的名称
     * @param time       频率限制时间
     * @param frequency  频率限制数量
     * @return true 表示访问频率没有超过限制,false 表示访问频率超过限制
     */
    private boolean checkAccessFrequency(String methodName, long time, int frequency) {
        long now = System.currentTimeMillis();
        List<Long> accessList = ACCESS_RECORD.get(methodName);
        if (accessList == null) {
            accessList = new ArrayList<>();
            ACCESS_RECORD.put(methodName, accessList);
        }
        accessList.add(now);
        while (!accessList.isEmpty() && now - accessList.get(0) > time) {
            accessList.remove(0);
        }
        return accessList.size() <= frequency;
    }
}

使用

@FrequencyLimit(frequency = 5, time = 60000L)
@PostMapping("/update")
    public R<?> update(@RequestBody ArticleBo articleBo) {
    articleService.update(articleBo);
    return R.ok(null, "修改成功");
}

收藏

点赞

打赏