<?php
class TrafficController {
private $capacity; // 桶的容量
private $rate; // 每秒产生的令牌数
private $tokens; // 当前桶中的令牌数
private $lastRefillTime; // 上次填充令牌的时间
private $waitingRequests; // 等待的请求队列
private $counters; // 用户访问计数器
public function __construct($capacity, $rate) {
$this->capacity = $capacity;
$this->rate = $rate;
$this->tokens = $capacity;
$this->lastRefillTime = time();
$this->waitingRequests = [];
$this->counters = [];
}
public function allowRequest($userId) {
$this->refillTokens();
if ($this->tokens < 1 || $this->exceedsRateLimit($userId)) {
$this->waitingRequests[$userId][] = time();
return false; // 请求被限流
}
$this->tokens--;
$this->counters[$userId]++;
return true; // 可以处理请求
}
private function refillTokens() {
$currentTime = time();
$this->tokens = min(
$this->capacity,
$this->tokens + ($currentTime - $this->lastRefillTime) * $this->rate
);
$this->lastRefillTime = $currentTime;
}
private function exceedsRateLimit($userId) {
$count = $this->counters[$userId] ?? 0;
return $count >= $this->rate;
}
}
// 使用示例
$trafficController = new TrafficController(10, 2); // 桶容量为10,每秒产生2个令牌
// 用户A发起请求
$userIdA = 1;
if ($trafficController->allowRequest($userIdA)) {
// 处理请求
echo "处理请求";
} else {
// 请求被限流,返回错误信息
echo "请求被限流";
}
// 用户B发起请求
$userIdB = 2;
if ($trafficController->allowRequest($userIdB)) {
// 处理请求
echo "处理请求";
} else {
// 请求被限流,返回错误信息
echo "请求被限流";
}
?>