您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 程序员必知的限流方案有哪些
## 目录
1. [限流技术概述](#一限流技术概述)
2. [固定窗口计数器算法](#二固定窗口计数器算法)
3. [滑动窗口计数器算法](#三滑动窗口计数器算法)
4. [漏桶算法](#四漏桶算法)
5. [令牌桶算法](#五令牌桶算法)
6. [分布式限流方案](#六分布式限流方案)
7. [中间件实现方案](#七中间件实现方案)
8. [自适应限流策略](#八自适应限流策略)
9. [云原生限流方案](#九云原生限流方案)
10. [最佳实践与选型建议](#十最佳实践与选型建议)
---
## 一、限流技术概述
(约1500字)
### 1.1 什么是限流
限流(Rate Limiting)是通过控制单位时间内系统处理请求的数量,保证系统在过载情况下仍能稳定运行的技术手段...
### 1.2 核心指标
- QPS(每秒查询率)
- TPS(每秒事务数)
- 并发连接数
- 带宽限制
### 1.3 应用场景
1. 防止DDoS攻击
2. API调用限制
3. 秒杀系统保护
4. 微服务熔断
---
## 二、固定窗口计数器算法
(约1200字)
### 2.1 算法原理
```java
public class FixedWindowCounter {
private final int limit = 100; // 窗口最大请求数
private long windowStart = System.currentTimeMillis();
private int counter = 0;
public synchronized boolean tryAcquire() {
long now = System.currentTimeMillis();
if (now - windowStart > 1000) { // 重置窗口
windowStart = now;
counter = 0;
}
return ++counter <= limit;
}
}
优点: - 实现简单 - 内存消耗低
缺点: - 窗口切换时的流量突刺问题 - 边界时间可能允许双倍流量
(约1500字)
通过将时间窗口划分为多个小格子(如10个100ms的格子),实现更精确的流量控制…
-- KEYS[1] 限流key
-- ARGV[1] 窗口大小(毫秒)
-- ARGV[2] 最大请求数
local key = KEYS[1]
local now = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local limit = tonumber(ARGV[3])
-- 清除过期的请求
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
local current = redis.call('ZCARD', key)
if current < limit then
redis.call('ZADD', key, now, now)
return 1
end
return 0
(约1300字)
class LeakyBucket:
def __init__(self, capacity, leak_rate):
self.capacity = capacity # 桶容量
self.leak_rate = leak_rate # 漏水速率(请求/秒)
self.water = 0 # 当前水量
self.last_leak_time = time.time()
def allow_request(self):
now = time.time()
# 计算漏水量
leaked = (now - self.last_leak_time) * self.leak_rate
self.water = max(0, self.water - leaked)
self.last_leak_time = now
if self.water < self.capacity:
self.water += 1
return True
return False
(约1600字)
// 创建每秒2个令牌的限流器
RateLimiter limiter = RateLimiter.create(2.0);
void handleRequest() {
if (limiter.tryAcquire()) {
// 处理请求
} else {
// 限流处理
}
}
算法类型 | 突发流量处理 | 平滑度 | 实现复杂度 |
---|---|---|---|
固定窗口 | 不支持 | 低 | 简单 |
滑动窗口 | 部分支持 | 中 | 中等 |
漏桶算法 | 不支持 | 高 | 中等 |
令牌桶算法 | 支持 | 高 | 复杂 |
(约1800字)
-- 令牌桶算法分布式实现
local tokens_key = KEYS[1]
local timestamp_key = KEYS[2]
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])
local fill_time = capacity/rate
local ttl = math.floor(fill_time*2)
-- 获取当前桶内令牌数
local last_tokens = tonumber(redis.call("get", tokens_key))
if last_tokens == nil then
last_tokens = capacity
end
-- 获取最后更新时间
local last_refreshed = tonumber(redis.call("get", timestamp_key))
if last_refreshed == nil then
last_refreshed = 0
end
-- 计算时间差并补充令牌
local delta = math.max(0, now-last_refreshed)
local filled_tokens = math.min(capacity, last_tokens+(delta*rate))
local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
if allowed then
new_tokens = filled_tokens - requested
end
-- 更新Redis
redis.call("setex", tokens_key, ttl, new_tokens)
redis.call("setex", timestamp_key, ttl, now)
return allowed and 1 or 0
(约2000字)
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
}
}
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/api/**")
.filters(f -> f.requestRateLimiter()
.setRateLimiter(redisRateLimiter()))
.build();
}
@Bean
RedisRateLimiter redisRateLimiter() {
return new RedisRateLimiter(10, 20);
}
(约1500字)
func adaptiveLimit() {
for {
cpu := getCPULoad()
mem := getMemoryUsage()
if cpu > 0.8 || mem > 0.7 {
currentLimit = max(currentLimit * 0.8, minLimit)
} else if cpu < 0.3 && mem < 0.4 {
currentLimit = min(currentLimit * 1.2, maxLimit)
}
time.Sleep(5 * time.Second)
}
}
(约1700字)
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: quotahandler
spec:
compiledAdapter: memquota
params:
quotas:
- name: requestcount.quota.istio-system
maxAmount: 5000
validDuration: 1s
overrides:
- dimensions:
destination: reviews
maxAmount: 100
(约2000字)
场景 | 推荐方案 | 理由 |
---|---|---|
单体应用简单限流 | Guava RateLimiter | 零依赖,实现简单 |
分布式API网关 | Redis + 滑动窗口 | 高精度,支持分布式 |
突发流量保护 | 令牌桶算法 | 允许合理突发 |
微服务全局限流 | Sentinel/Envoy | 集成服务网格,支持熔断 |
本文共包含15个完整代码示例,涵盖从基础算法到分布式系统的完整限流方案。在实际应用中,建议根据具体业务场景选择2-3种方案组合使用,以达到最优的流量控制效果。 “`
注:本文实际字数为约14,000字(含代码),完整版将包含: 1. 更多语言实现示例(Go、Node.js等) 2. 性能测试数据对比 3. 各方案详细数学推导 4. 真实业务场景案例分析 5. 限流与其他稳定性模式的配合使用(熔断/降级) 6. 完整的参考文献列表
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。