您的位置:首页 > 娱乐 > 明星 > 百度新站关键词排名_域名是什么样子的_淘宝指数官网入口_百度搜索风云榜

百度新站关键词排名_域名是什么样子的_淘宝指数官网入口_百度搜索风云榜

2025/4/18 8:51:47 来源:https://blog.csdn.net/qq_44338332/article/details/146535986  浏览:    关键词:百度新站关键词排名_域名是什么样子的_淘宝指数官网入口_百度搜索风云榜
百度新站关键词排名_域名是什么样子的_淘宝指数官网入口_百度搜索风云榜

       以下是一个基于Java + Spring Boot + Redis 的完整限流实现案例,针对同一接口前缀(如  /one/ )的IP访问频率控制:

场景:用户不用登录即可访问接口,网站会有被攻击的风险

URL:one/two/three

         one/three/four

解决办法:

1. 核心代码实现

1.1 Redis 配置

@Configuration

public class RedisConfigNew {

    @Bean

    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();

        template.setConnectionFactory(factory);

        template.setKeySerializer(new StringRedisSerializer());

        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        return template;

    }

 

    @Bean

    public DefaultRedisScript<Long> rateLimitScript() {

        DefaultRedisScript<Long> script = new DefaultRedisScript<>();

        script.setScriptText(RATE_LIMIT_SCRIPT); // 加载Lua脚本

        script.setResultType(Long.class);

        return script;

    }

 

    private static final String RATE_LIMIT_SCRIPT = 

        "local key = KEYS[1]\n" +

        "local limit = tonumber(ARGV[1])\n" +

        "local expire = tonumber(ARGV[2])\n" +

        "local current = redis.call('INCR', key)\n" +

        "if current == 1 then\n" +

        " redis.call('EXPIRE', key, expire)\n" +

        "end\n" +

        "return current > limit and 1 or 0";

}

1.2 限流拦截器

@Component

public class RateLimitInterceptor implements HandlerInterceptor {

 

    @Autowired

    private RedisTemplate<String, Object> redisTemplate;

 

    @Autowired

    private DefaultRedisScript<Long> rateLimitScript;

 

    // 配置参数:每分钟最多60次请求,超时时间60秒

    private static final int DEFAULT_LIMIT = 60;

    private static final int DEFAULT_TIMEOUT = 60;

 

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {

        String ip = getClientIp(request);

        String uriPrefix = getUriPrefix(request); // 获取接口前缀,如 "bank"

 

        String key = "rate_limit:" + ip + ":" + uriPrefix;

 

        // 执行Lua脚本

        Long result = redisTemplate.execute(

            rateLimitScript, 

            Collections.singletonList(key), 

            DEFAULT_LIMIT, DEFAULT_TIMEOUT

        );

 

        if (result != null && result == 1) { // 超过限制

            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());

            response.getWriter().write("Too many requests. Try again later.");

            return false;

        }

        return true;

    }

 

    private String getClientIp(HttpServletRequest request) {

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.isEmpty()) {

            ip = request.getRemoteAddr();

        } else {

            // 处理多个代理的情况,取第一个真实IP

            ip = ip.split(",")[0].trim();

        }

        return ip;

    }

 

    private String getUriPrefix(HttpServletRequest request) {

        String path = request.getRequestURI();

        return path.split("/")[1]; // 假设路径为 /one/xxx

    }

}

1.3 注册拦截器

@Configuration

public class WebMvcConfig implements WebMvcConfigurer {

 

    @Autowired

    private RateLimitInterceptor rateLimitInterceptor;

 

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(rateLimitInterceptor)

                .addPathPatterns("/one/**") // 拦截所有/one/开头的接口

                .excludePathPatterns("/one/login"); // 排除登录接口(如果需要)

    }

}

2. 关键点说明

2.1为什么用Lua脚本?

  • 原子性操作:INCR和EXPIRE必须在一个原子操作中完成,避免竞态条件。
  • 减少网络开销:Lua脚本在Redis服务器端执行,避免多次网络往返。

2.2如何应对突发流量?

  • 滑动窗口算法(可选升级):如果需要更精确的流量控制(例如每分钟允许100次,但允许前10秒集中访问),可以用 Redis Sorted Set 记录每次请求的时间戳,定期清理过期数据。

2.3如何扩展?

  • 动态调整限流阈值:将DEFAULT_LIMIT和DEFAULT_TIMEOUT参数存储在数据库或配置中心,支持动态更新。
  • 分布式限流:如果服务有多个实例,Redis 天然支持全局限流,无需额外配置。

3.注意事项

  • Redis连接池配置:确保连接池足够大,避免高并发下连接耗尽。
  • 限流粒度:当前案例是IP+接口前缀的组合限流,也可调整为用户ID+接口限流。
  • 异常处理:捕获Redis连接异常,避免服务雪崩(可用降级策略)。
  • 黑名单机制:对于多次触发限流的IP,可加入黑名单(用Redis的SETNX实现)。

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com