Skip to content

接口限流

youlai-boot 提供基于 IP 的全局限流机制,通过过滤器实现接口级别的并发控制。

限流方式

方式实现位置说明
IP 全局限流RateLimiterFilter基于令牌桶算法,全局限流所有接口

实现原理

过滤器链

限流过滤器位于 Spring Security 过滤器链前端:

Redis Key 设计

Key: rate_limiter:ip:{ip}
Value: 请求计数
TTL: 1 秒

示例

rate_limiter:ip:192.168.1.100

核心算法

令牌桶算法

  1. 每个 IP 在 1 秒时间窗口内统计请求次数
  2. 首次访问时设置 Key,过期时间 1 秒
  3. 每次请求自增计数
  4. 计数超出阈值时触发限流

核心代码

java
public boolean rateLimit(String ip) {
    String key = StrUtil.format(RedisConstants.RateLimiter.IP, ip);
    
    // 自增请求计数
    Long count = redisTemplate.opsForValue().increment(key);
    if (count == null || count == 1) {
        // 第一次访问时设置过期时间为 1 秒
        redisTemplate.expire(key, 1, TimeUnit.SECONDS);
    }
    
    // 获取系统配置的限流阈值
    Object systemConfig = configService.getSystemConfig(
        SystemConstants.SYSTEM_CONFIG_IP_QPS_LIMIT_KEY
    );
    if (systemConfig == null) {
        return false; // 未配置则跳过限流
    }
    
    long limit = Convert.toLong(systemConfig, DEFAULT_IP_LIMIT);
    return count != null && count > limit;
}

配置说明

限流阈值配置

通过系统配置管理限流阈值:

配置 KeyIP_QPS_THRESHOLD_LIMIT

配置方式

在系统管理 → 系统配置中添加:

配置键配置值说明
IP_QPS_THRESHOLD_LIMIT10单 IP 每秒最大请求数

默认值

  • 未配置时:跳过限流
  • 配置为空时:默认 10 次/秒

过滤器注册

SecurityConfig 中注册:

java
.addFilterBefore(
    new RateLimiterFilter(redisTemplate, configService), 
    UsernamePasswordAuthenticationFilter.class
)

过滤器位置:在用户名密码认证过滤器之前执行。

错误响应

当触发限流时,返回以下响应:

json
{
  "code": "A0502",
  "msg": "请求并发数超出限制",
  "data": null
}

错误码说明

错误码HTTP 状态码说明
A0502429请求并发数超出限制

应用场景

全局防护

适用于所有接口的全局限流:

  • 防止恶意请求攻击
  • 保护系统资源
  • 限制爬虫抓取

典型场景

场景建议阈值说明
普通应用10-50 次/秒正常业务流量
高并发应用100-500 次/秒促销、活动场景
API 网关1000+ 次/秒大流量入口

与其他限流方案对比

方案实现方式优势劣势
IP 全局限流(当前)Redis + Filter实现简单、全局生效粒度较粗
接口级限流注解 + AOP精确控制每个接口配置繁琐
用户级限流用户 ID + Redis防止单用户滥用需要登录态
分布式限流Redis + Lua集群环境精确控制实现复杂

扩展建议

1. 接口级限流

参考 Django 版本的装饰器方式,实现接口级限流:

java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int value() default 60; // 限流时间(秒)
    String message() default "操作频繁,请稍后再试";
}

使用示例

java
@PostMapping("/sms/code")
@RateLimit(value = 60)
public Result<?> sendSmsCode(@RequestParam String mobile) {
    // 发送短信验证码
}

2. 多维度限流

扩展为多维度限流:

java
public enum RateLimitType {
    IP,      // IP 限流
    USER,    // 用户限流
    GLOBAL   // 全局限流
}

3. 动态配置

支持接口级动态配置:

java
@RateLimit(key = "sms_code", fallbackValue = 60)
public Result<?> sendSmsCode() {
    // 从配置中心读取限流时间
}

相关文件

文件说明
core/filter/RateLimiterFilter.javaIP 限流过滤器
config/SecurityConfig.java过滤器注册配置
common/constant/RedisConstants.javaRedis Key 常量
common/constant/SystemConstants.java系统配置常量
core/web/ResultCode.java错误码定义

基于 MIT 许可发布