计数器算法实现起来比较简单,它的基本思路是:在单位时间内(如 1 秒钟)对访问次数进行计数,如果超过设定的阈值,则拒绝后续的请求。以下是一个使用 PHP 实现的计数器算法。

1679371178

完整代码

class Counter {
    protected $maxCount = 100; // 设定最大请求数
    protected $interval = 60;  // 设定时间窗口大小,单位为秒
    protected $redis = null;   // Redis 连接

    public function __construct($maxCount, $interval) {
        $this->maxCount = $maxCount;
        $this->interval = $interval;

        // 建立 Redis 连接
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }

    public function check($key) {
        // 获取当前计数器的值
        $count = intval($this->redis->get($key));
        if ($count >= $this->maxCount) {
            // 超过最大允许的请求数,返回 false 表示被限流了
            return false;
        } else {
            // 自增计数器并设置过期时间
            $this->redis->multi()
                ->incr($key)
                ->expire($key, $this->interval)
                ->exec();

            return true;
        }
    }
}

// 使用示例
$counter = new Counter(100, 60);
if ($counter->check('user:123')) {
    // 请求处理逻辑
} else {
    // 被限流了,返回错误码或提示信息
}

 以上代码中,Counter 类包含了三个成员变量:$maxCount 表示最大请求数,$interval 表示时间窗口大小,$redis 是与 Redis 数据库建立的连接对象。在 check 方法中,我们首先从 Redis 中获取当前请求计数器的值,如果超过了 $maxCount,则返回 false 表示被限流了;否则自增计数器的值,并使用 $interval 设置过期时间。如果在时间窗口内再次请求同一个 key,则会继续自增计数器的值,直到超过 $maxCount