首先,在使用Redis进行全局限流前,需要安装并启动Redis服务,并在Spring Boot项目中引入Redis依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
**
然后,我们在项目中添加一个工具类RedisRateLimiter,用来实现基于Redis的全局限流:
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
public class RedisRateLimiter {
private RedisTemplate<String, String> redisTemplate;
public RedisRateLimiter(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 检查是否超出限制
* @param key 限流的key
* @param maxCount 限制次数
* @param expireSeconds 时间段
* @return 是否超限
*/
public boolean checkRate(String key, int maxCount, int expireSeconds) {
String redisKey = key + System.currentTimeMillis() / (expireSeconds * 1000);
Long count = redisTemplate.opsForValue().increment(redisKey, 1);
if (count == 1) {
redisTemplate.expire(redisKey, expireSeconds, TimeUnit.SECONDS);
}
return count > maxCount;
}
}
**
这个类中,我们通过Redis的Increment方法实现接口的调用计数,每次使用一个特定的key,来判断当前时间段内是否超出限制。如果累计调用次数超过了限制,就返回 true,否则返回 false。
下面是一个基于RedisRateLimiter的Controller示例代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
public class DemoController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@GetMapping("/demo")
public String demo() {
RedisRateLimiter rateLimiter = new RedisRateLimiter(redisTemplate);
if (rateLimiter.checkRate("my_key", 100, 60)) {
return "请求太过频繁,请稍后再试!";
} else {
//业务逻辑代码
return "请求正常!";
}
}
}
**
在Controller中,我们通过RedisRateLimiter判断每个请求是否超出限制,如果超出,就返回错误提示;如果没有超出,就执行正常的业务逻辑代码。
需要注意的是,RedisRateLimiter适用于单个应用程序进程的全局限流,如果要进行分布式限流,可以使用key-prefix标记方法调用请求,并将限流的数据放入Redis Cluster或者Redis Sentinel集群中。当然,具体实现方式需要根据实际情况进行调整。