在高并发系统中,限流是一项非常重要的技术手段,用于保护后端服务,防止因流量过大导致系统崩溃。本文将详细介绍如何使用 Redisson 提供的
RRateLimiter
实现分布式限流,以及其原理、使用场景和完整代码示例。
目录
[二、为什么选择 Redisson 实现分布式限流?](#二、为什么选择 Redisson 实现分布式限流?)
[三、使用 Redisson 的 RRateLimiter 实现限流](#三、使用 Redisson 的 RRateLimiter 实现限流)
[1.1 引入依赖](#1.1 引入依赖)
[1.2 配置 Redis](#1.2 配置 Redis)
[2.1 配置 Redisson 客户端 在 Spring Boot 中自动注入 RedissonClient](#2.1 配置 Redisson 客户端 在 Spring Boot 中自动注入 RedissonClient)
[2.2 实现限流功能 创建一个基于 RRateLimiter 的限流工具类](#2.2 实现限流功能 创建一个基于 RRateLimiter 的限流工具类)
[2.3 调用限流服务 在 Controller 中调用限流逻辑](#2.3 调用限流服务 在 Controller 中调用限流逻辑)
[六、Redisson 限流实现的原理](#六、Redisson 限流实现的原理)
一、什么是限流
限流(Rate Limiting)是对接口访问速率进行限制的技术手段,用于:
- 保护服务:避免瞬间大流量压垮后端系统。
- 公平分配资源:防止个别用户或服务消耗过多资源。
- 防刷机制:防止恶意请求或攻击。
常见的限流算法
- 漏桶算法(Leaky Bucket):将请求按照固定速率流出,多余的请求会被丢弃。
- 令牌桶算法(Token Bucket):按照固定速率生成令牌,请求需消耗令牌才能被处理。
Redisson 的限流机制基于令牌桶算法。
二、为什么选择 Redisson 实现分布式限流?
- 简单易用:Redisson 是一个强大的 Redis 客户端,封装了丰富的分布式工具。
- 高性能:借助 Redis 实现分布式数据存储与计算,支持高并发场景。
- 可扩展性强:支持多种限流场景,例如接口限流、用户限流、IP 限流等。
三、使用 Redisson 的 RRateLimiter 实现限流
RRateLimiter 是 Redisson 提供的分布式限流组件,支持令牌桶算法。
主要功能
- 设置限流规则:包括令牌生成速率和时间窗口。
- 请求令牌:通过消耗令牌来完成请求控制。
- 分布式支持:多个服务实例共享同一个限流器。
四、实现步骤
以下是使用 Redisson 限流的完整步骤:
1.环境准备
1.1 引入依赖
java
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.21.0</version>
</dependency>
1.2 配置 Redis
在 application.yml 文件中配置 Redis 连接:
java
spring:
redis:
host: 127.0.0.1
port: 6379
2.编写限流逻辑
2.1 配置 Redisson 客户端 在 Spring Boot 中自动注入 RedissonClient
java
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
return Redisson.create(config);
}
}
2.2 实现限流功能 创建一个基于 RRateLimiter 的限流工具类
java
@Service
public class RateLimiterService {
@Autowired
private RedissonClient redissonClient;
public boolean tryAcquire(String key, long rate, long rateInterval, long timeout, TimeUnit unit) {
// 获取限流器
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
// 配置限流规则
rateLimiter.trySetRate(RateType.OVERALL, rate, rateInterval, RateIntervalUnit.SECONDS);
// 尝试获取令牌
return rateLimiter.tryAcquire(1, timeout, unit);
}
}
2.3 调用限流服务 在 Controller 中调用限流逻辑
java
@RestController
@RequestMapping("/api")
public class ApiController {
@Autowired
private RateLimiterService rateLimiterService;
@PostMapping("/access")
public ResponseEntity<String> accessApi() {
String key = "api:access";
long rate = 100; // 每秒生成 100 个令牌
long rateInterval = 1;
boolean allowed = rateLimiterService.tryAcquire(key, rate, rateInterval, 0, TimeUnit.SECONDS);
if (!allowed) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("请求过多,请稍后再试");
}
return ResponseEntity.ok("请求成功");
}
}
五、测试限流效果
- 启动服务后,使用工具(如 Postman 或 JMeter)模拟并发访问。
- 根据
rate
参数设置,每秒最多允许 100 个请求通过,超出限制的请求会被拒绝并返回错误提示。
六、Redisson 限流实现的原理
-
令牌桶算法
- 令牌生成 :每隔
rateInterval
秒生成rate
个令牌。 - 令牌消耗:每个请求消耗一个令牌,如果令牌不足则拒绝请求。
- 存储:令牌的生成和消耗通过 Redis 实现,因此支持分布式场景。
- 令牌生成 :每隔
-
Redis 实现 Redisson 使用 Redis 的原子操作(如
EVAL
)实现令牌的生成与消耗,从而保证数据一致性和高效性。
七、常见应用场景
- 接口限流
- 限制用户访问某个接口的频率,保护后端服务。
- IP 限流
- 对同一个 IP 地址的访问进行限制,防止恶意攻击。
- 用户限流
- 针对不同用户设置个性化的限流规则。
八、限流注意事项
- 合理设置限流参数
- 根据业务场景评估每秒允许的最大请求数和时间窗口大小。
- 配合熔断机制
- 当限流触发时,可以使用熔断机制返回备用响应。
- 防止误锁
- 在使用分布式限流时,确保限流器的 Key 是唯一的,避免不同接口共享同一个限流器。
点个关注,不会迷路!