Java面试通关秘籍:深入解析滑动窗口限流算法原理与实战

一、引言
滑动窗口限流算法是Java面试中的高频考点,尤其在分布式系统中,对系统的高可用和性能至关重要。本文将从原理、实现、优缺点及实战案例等方面深入解析滑动窗口限流算法,帮助读者在面试中脱颖而出。
二、滑动窗口限流算法原理
滑动窗口限流算法是一种时间窗口限流算法,通过维护一个时间窗口内的请求次数,当请求次数超过设定的阈值时,拒绝新请求。其核心思想是:固定时间窗口内,只允许一定数量的请求通过。
三、滑动窗口限流算法实现
1.计数器法
计数器法是最简单的滑动窗口限流算法实现,通过维护一个计数器记录窗口内的请求次数。当请求到来时,计数器加1;当窗口结束时,重置计数器。
```java
public class CounterLimiter {
private int count = 0;
private int limit = 100; // 每秒最多100个请求
private long startTime = System.currentTimeMillis();
private long windowSize = 1000; // 时间窗口大小,1秒
public boolean isAllow() {
long now = System.currentTimeMillis();
if (now - startTime >= windowSize) {
count = 0;
startTime = now;
}
if (count < limit) {
count++;
return true;
}
return false;
}
}
```
2.令牌桶法
令牌桶法是一种更精确的滑动窗口限流算法,通过维护一个令牌桶,当请求到来时,从桶中取出一个令牌;当桶中没有令牌时,拒绝新请求。
```java
public class TokenBucketLimiter {
private int tokens = 100; // 桶中初始令牌数
private int limit = 100; // 每秒最多100个请求
private long lastTime = System.currentTimeMillis();
public boolean isAllow() {
long now = System.currentTimeMillis();
long delta = now - lastTime;
tokens += delta * limit / 1000; // 每秒增加的令牌数
tokens = Math.min(tokens, limit);
lastTime = now;
if (tokens > 0) {
tokens--;
return true;
}
return false;
}
}
```
3.漏桶法
漏桶法是一种模拟水桶漏水的限流算法,当请求到来时,将请求放入桶中;当桶满时,拒绝新请求。
```java
public class BucketLimiter {
private int capacity = 100; // 桶容量
private int tokens = 0; // 桶中剩余令牌数
private long lastTime = System.currentTimeMillis();
public boolean isAllow() {
long now = System.currentTimeMillis();
long delta = now - lastTime;
tokens += delta * capacity / 1000; // 每秒增加的令牌数
tokens = Math.min(tokens, capacity);
lastTime = now;
if (tokens > 0) {
tokens--;
return true;
}
return false;
}
}
```
四、滑动窗口限流算法优缺点
1.优点
(1)实现简单,易于理解。
(2)可灵活调整时间窗口大小和阈值。
(3)适用于高并发场景。
2.缺点
(1)计数器法在窗口结束时需要重置计数器,可能导致性能损耗。
(2)令牌桶法和漏桶法需要维护一个桶,增加内存消耗。
五、实战案例
以下是一个使用滑动窗口限流算法的Spring Boot项目示例,通过拦截器对请求进行限流。
```java
@Configuration
public class LimiterConfig {
@Bean
public HandlerInterceptorRegistry registry() {
HandlerInterceptorRegistry registry = new HandlerInterceptorRegistry();
registry.addInterceptor(new LimiterInterceptor()).addPathPatterns("/**");
return registry;
}
}
public class LimiterInterceptor implements HandlerInterceptor {
private TokenBucketLimiter limiter = new TokenBucketLimiter();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!limiter.isAllow()) {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
return false;
}
return true;
}
}
```
六、总结
滑动窗口限流算法是Java面试中的高频考点,掌握其原理和实现对于开发高性能、高可用的分布式系统具有重要意义。本文详细解析了滑动窗口限流算法的原理、实现、优缺点及实战案例,希望对读者有所帮助。






