Rate Limiter Plugin
对应模块:
io.gitee.lcgyl:lcgyl-rate-limiter-plugin
高并发限流组件,保护核心服务免受流量洪峰冲击。
✨ 特性
- ✅ 多维度限流 - 支持按 IP, 用户, API, 全局等多维度组合
- ✅ 经典算法 - 内置令牌桶, 漏桶, 滑动窗口, 固定窗口算法
- ✅ 分布式限流 - 基于 Redis Lua 脚本实现精准的分布式控制
- ✅ 注解驱动 -
@RateLimit轻松接入 - ✅ 结构化日志 - StructuredRateLimiterLogger 统计输出
v2.2.0
🚀 快速开始
依赖引入
gradle
implementation 'io.gitee.lcgyl:lcgyl-rate-limiter-plugin:2.2.0'配置
yaml
lcgyl:
rate-limiter:
enabled: true
type: redis # local, redis
redis:
key-prefix: "ratelimit:"
default:
limit: 100
window: 1m
algorithm: sliding_window # token_bucket, leaky_bucket, sliding_window, fixed_window声明式限流(推荐)
java
@RestController
@RequestMapping("/api")
public class ApiController {
// 简单限流:每分钟最多 100 次请求
@RateLimit(limit = 100, window = "1m")
@GetMapping("/products")
public List<Product> listProducts() {
return productService.findAll();
}
// 按用户限流:每个用户每秒最多 10 次
@RateLimit(limit = 10, window = "1s", keyResolver = "#userId")
@PostMapping("/orders")
public Order createOrder(@RequestParam String userId, @RequestBody OrderRequest request) {
return orderService.create(userId, request);
}
// 按 IP 限流 + 自定义降级
@RateLimit(limit = 5, window = "1s", keyResolver = "#request.remoteAddr", fallback = "fallbackMethod")
@GetMapping("/sensitive")
public Data getSensitiveData(HttpServletRequest request) {
return dataService.getSensitive();
}
public Data fallbackMethod(HttpServletRequest request) {
return Data.cached(); // 返回缓存数据作为降级
}
}编程式限流
java
@Service
public class SmsService {
@Inject
private RateLimiter rateLimiter;
public void sendSms(String phone, String content) {
String key = "sms:" + phone;
// 检查是否允许请求
if (!rateLimiter.tryAcquire(key, 5, Duration.ofMinutes(1))) {
throw new RateLimitExceededException("短信发送频率过高,请稍后再试");
}
// 发送短信
smsGateway.send(phone, content);
}
}v2.2.0 新功能:限流统计日志
java
@Service
public class RateLimitMonitor {
@Inject
private StructuredRateLimiterLogger rateLimitLogger;
// 记录限流事件
public void logRateLimitEvent(String key, boolean allowed) {
rateLimitLogger.info("rate.limit.check")
.field("key", key)
.field("allowed", allowed)
.field("timestamp", System.currentTimeMillis())
.log();
}
// 定期输出统计
@Scheduled(fixedRate = 60000)
public void logStatistics() {
rateLimitLogger.info("rate.limit.stats")
.field("totalRequests", metrics.getTotalRequests())
.field("blockedRequests", metrics.getBlockedRequests())
.field("blockRate", metrics.getBlockRate())
.log();
}
}