Spring Boot + Redis 实现接口防抖与限流实战指南

test content

在高并发场景中,接口防抖与限流是保护系统的两道重要防线。本文结合实战,讲解如何用Redis+Spring Boot实现一套灵活的接口保护机制。## 一、为什么需要防抖与限流?防抖(Debounce) :用户连续点击提交按钮,只执行最后一次请求。比如点赞、评论场景,防止重复提交。限流(Rate Limit) :限制接口在单位时间内的调用次数。比如秒杀、抢票场景,保护后端服务不被冲垮。两者相辅相成:防抖解决「用户手速」问题,限流解决「流量洪峰」问题。 ## 二、技术方案设计### 2.1 引入依赖xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId></dependency>### 2.2 自定义注解 @RateLimitjava@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface RateLimit { // 限流key前缀 String key() default "rate:limit:"; // 时间窗口(秒) int window() default 60; // 最大请求次数 int maxRequests() default 100; // 是否启用防抖 boolean debounce() default false;}### 2.3 Redis+Lua脚本实现原子操作java@Componentpublic class RateLimitService { @Autowired private StringRedisTemplate redisTemplate; private static final String LUA_SCRIPT = "local key = KEYS[1]\n" + "local limit = tonumber(ARGV[1])\n" + "local window = tonumber(ARGV[2])\n" + "local current = redis.call('get', key)\n" + "if current and tonumber(current) >= limit then\n" + " return 0\n" + "end\n" + "current = redis.call('incr', key)\n" + "if tonumber(current) == 1 then\n" + " redis.call('expire', key, window)\n" + "end\n" + "return 1"; public boolean isAllowed(String key, int limit, int window) { DefaultRedisScript<Long> script = new DefaultRedisScript<>(LUA_SCRIPT, Long.class); Long result = redisTemplate.execute(script, Collections.singletonList(key), String.valueOf(limit), String.valueOf(window)); return result != null && result == 1; }}### 2.4 AOP切面统一处理java@Aspect@Component@Slf4jpublic class RateLimitAspect { @Autowired private RateLimitService rateLimitService; @Around("@annotation(rateLimit)") public Object around(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable { String key = rateLimit.key() + getClientIp(); // 限流检查 if (!rateLimit.debounce()) { if (!rateLimitService.isAllowed(key, rateLimit.maxRequests(), rateLimit.window())) { throw new BusinessException("请求太频繁,请稍后再试"); } } else { // 防抖:使用Redis SETNX保证只有一个请求被执行 String debounceKey = "debounce:" + key; Boolean success = redisTemplate.opsForValue().setIfAbsent( debounceKey, "1", Duration.ofSeconds(rateLimit.window())); if (!success) { return Result.fail("操作太频繁"); } } return joinPoint.proceed(); } private String getClientIp() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); return request.getRemoteAddr(); }}## 三、使用示例java@RestControllerpublic class OrderController { // 限流:60秒内最多访问200次 @RateLimit(key = "order:create:", window = 60, maxRequests = 200) @PostMapping("/api/order/create") public Result createOrder(@RequestBody OrderDTO order) { // 业务逻辑 return Result.success(orderService.create(order)); } // 防抖:点赞场景,5秒内只执行一次 @RateLimit(key = "post:like:", window = 5, maxRequests = 1, debounce = true) @PostMapping("/api/post/like") public Result likePost(@RequestParam Long postId) { return Result.success(postService.like(postId)); }}## 四、线上部署注意事项1. Redis集群部署 :单机Redis在极端高并发下可能成为瓶颈2. 限流策略分级 :普通用户 vs VIP用户,差异化限流3. 降级策略 :Redis不可用时,自动放行请求,避免服务不可用4. 监控告警 :接入Prometheus,监控限流触发次数## 五、总结通过@RateLimit注解+AOP+Redis Lua脚本,我们实现了一套轻量、可复用、易配置 的接口保护方案:| 特性 | 防抖 | 限流 ||------|------|------|| 解决问题 | 重复提交 | 流量冲击 || 核心机制 | SETNX | INCR+EXPIRE || 适用场景 | 点赞、评论 | 秒杀、查询 |希望这篇实战指南对你有帮助!有问题欢迎评论区交流~---往期推荐: - Spring Boot 异步任务详解- Redis分布式锁的七种避坑指南

相关推荐
V+zmm101342 小时前
毕业设计:基于neo4j的知识图谱的智能问答系统(源码)
spring boot·毕业设计·知识图谱·课程设计·neo4j·智能问答·毕设
直奔標竿3 小时前
Java开发者AI转型第二十三课!Spring AI个人知识库实战(二):异步ETL流水线搭建与避坑指南
java·人工智能·spring boot·后端·spring
Lyyaoo.3 小时前
TreadLocal和TreadLocalMap
android·java·redis
浮尘笔记3 小时前
在Snowy后台无需编码实现自动化生成CRUD操作流程
java·开发语言·经验分享·spring boot·后端·程序人生·mybatis
JAVA面经实录9173 小时前
Spring Boot + Spring AI 一体化实战全文档
java·人工智能·spring boot·spring
为美好的生活献上中指3 小时前
本地虚拟机部署redis集群
前端·redis·ubuntu·bootstrap·html·redis集群
希望永不加班3 小时前
SpringBoot 接口签名验证(AppKey/Secret)
java·spring boot·后端·spring
a8a3024 小时前
Laravel7.x核心特性全解析
java·spring boot·后端
aLTttY4 小时前
Spring Boot集成AI大模型实战:从0到1打造智能应用
人工智能·spring boot·后端