下面我们通过php使用redis实现一个简单通用的滑动窗口限流算法

1679047362

解决问题

 滑动窗口算法主要解决了传统计数限流算法的阶段突发性流量问题。

具体实现

  • 创建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());

 通过以上代码我们实现滑动窗口限流算法,有兴趣的同学可以尝试一下