space107

  • 首页
  • 文章分类
    • 后端汇总
    • 运维汇总
    • 数据库汇总
space107的个人分享博客
  1. 首页
  2. 文章分类
  3. 后端汇总
  4. 正文

基于springboot的接口防刷

2025年7月14日 22点热度 0人点赞 0条评论

接口防刷设计实现


redis+apo 实现限流防刷
设计注解类 注解类自带参数 maxcount 最大次数, time 时间, limitType限流类型,limitMag 提示信息
实现思路
设置切面类 aspect 自定义注解limit 并实现注解
注解实现类思路
redis实现对每个ip的记录 使用redis increment实现自增 比较当前ip的单位时间内的访问次数 与最大次数的比较
如果没有 可以新增key key的设置可以是 ip+方法名 或者其他 实现自定义接口单独限制
并为 key设置过期时间 实现单位时间内实现限制

代码参考

@Aspect
@Component
@RequiredArgsConstructor
public class RateLimiterAspect {

    @Resource(name = "defaultRedisUtil")
    RedisUtil redisUtil;

    @Before("@annotation(rateLimiter)")
    public void doBefore(JoinPoint point, LxRateLimit rateLimiter) throws Throwable {
        int time = rateLimiter.time();
        int count = rateLimiter.count();
        long total = 1L;
        String key = getCombineKey(rateLimiter, point);

        try {
            if (redisUtil.hasKey(key)) {
                total = redisUtil.incr(key, 1); // 请求进来,对应的key加1
                if (total > count) {
                    throw new IpExceedException(rateLimiter.limitMsg());
                }
            } else {
                redisUtil.set(key, 1, time); // 初始化key
            }
        } catch (IpExceedException e) {//频繁进入

            throw e;
        } catch (Exception e) {
            throw new Exception("网络繁忙,请稍候再试");
        }
    }

    // 获取限流key
    public String getCombineKey(LxRateLimit rateLimiter, JoinPoint point) {
        StringBuffer stringBuffer = new StringBuffer("key");
        if (rateLimiter.limitType() == 0) {//IP
            stringBuffer.append(WebUtil.getIP(WebUtil.getRequest())).append("-");
        }
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        Class<?> targetClass = method.getDeclaringClass();
        stringBuffer.append(targetClass.getName()).append("-").append(method.getName());
        return stringBuffer.toString();
    }
}

/**
 * 限流注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LxRateLimit {
    // 限流时间,单位秒
    int time() default 60;
    // 限制最大请求次数
    int count() default 100;
    // 限流类型(默认为IP限流) 0:IP
    int limitType() default 0;
    // 限流后返回的提示信息
    String limitMsg() default "Frequent visits, please try again later";
}

补充:

标签: redis 代码层面
最后更新:2025年7月24日

space107

技术分享+知识汇总

点赞
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

归档

  • 2025 年 7 月

分类

  • 后端汇总
  • 数据库汇总
  • 运维汇总
最新 热点 随机
最新 热点 随机
docker离线安装 分库分表初始化建表 jdk增加ca证书 es数据库迁移 阿里云oss方案 ssh升级更新(qilin) 布隆过滤器原理 以及使用常见
docker离线安装 分库分表初始化建表 jdk增加ca证书 基于springboot的接口防刷 ssh升级更新(qilin) 布隆过滤器原理 以及使用常见

COPYRIGHT © 2025 space107. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备2025140917号-1