platform = $platform; $this->apiName = $apiName; $this->config = config("rate_limits.{$platform}.{$apiName}", []); } public function allowRequest() { return true; // 临时绕过限流 $key = "rate_limit:{$this->platform}:{$this->apiName}"; // 使用 Redis 计数器,每秒重置 $current = Redis::incr($key); if ($current == 1) { Redis::expire($key, 1); } $qps = $this->config['qps'] ?? 2; if ($current > $qps) { return false; } // 分钟限制 $minKey = "rate_limit_min:{$this->platform}:{$this->apiName}:" . date('YmdHi'); $minCurrent = Redis::incr($minKey); if ($minCurrent == 1) { Redis::expire($minKey, 60); } $minLimit = $this->config['minute'] ?? 30; if ($minCurrent > $minLimit) { return false; } // 日限制 $dayKey = "rate_limit_day:{$this->platform}:{$this->apiName}:" . date('Ymd'); $dayCurrent = Redis::incr($dayKey); if ($dayCurrent == 1) { Redis::expire($dayKey, 86400); } $dayLimit = $this->config['daily'] ?? 1000; if ($dayCurrent > $dayLimit) { return false; } return true; } public function waitForAvailability($timeout = 60) { $start = time(); while (time() - $start < $timeout) { if ($this->allowRequest()) { return true; } // 指数退避 $wait = min(5, pow(2, time() - $start)); sleep($wait); } return false; } }