下面我们通过php使用redis实现一个简单通用的滑动窗口限流算法
解决问题
滑动窗口算法主要解决了传统计数限流算法的阶段突发性流量问题。
具体实现
- 创建redis对象并定义缓存键
$redis = new \Redis();
$redis->connect("127.0.0.1");
$key = "aaaaa";
- 定义每分钟最大请求数量
$max_count = 320;
$total_s = 60;
$current_time = time();
- 计算平均值用于限制每秒请求数量
$avg_count = ceil($max_count / $total_s);
- 限制每秒请求数量
$range_count = $redis->zRangeByScore($key, $current_time, $current_time);
if (count($range_count) > $avg_count) {
exit('请求太过频繁,请稍后 -1');
}
- 限制每分钟请求数量
$redis->zRemRangeByScore($key, 0, $current_time - 59);
$count = $redis->zCard($key);
if ($count >= $max_count) {
exit('请求太过频繁,请稍后');
}
- 统计计数
$redis->zAdd($key, $current_time, random());
完整代码
$redis = new \Redis();
$redis->connect("127.0.0.1");
$max_count = 320;
$total_s = 60;
$current_time = time();
$avg_count = (int)($max_count / $total_s);
$key = "aaaaa";
$range_count = $redis->zRangeByScore($key, $current_time, $current_time);
if (count($range_count) > $avg_count) {
exit('请求太过频繁,请稍后 -1');
}
$redis->zRemRangeByScore($key, 0, $current_time - 59);
$count = $redis->zCard($key);
if ($count >= $max_count) {
exit('请求太过频繁,请稍后');
}
$redis->zAdd($key, $current_time, random());
通过以上代码我们实现滑动窗口限流算法,有兴趣的同学可以尝试一下