LimitQps.php 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. <?php
  2. namespace App\Http\Middleware;
  3. use App\DataApiNew\Models\AgentApi;
  4. use App\DataApiNew\Models\BlackList;
  5. use Closure;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Facades\Redis;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Vinkla\Hashids\Facades\Hashids;
  10. class LimitQps
  11. {
  12. public $maxRequestsPerSecond = 10;
  13. /**
  14. * 处理请求。
  15. *
  16. * @param \Illuminate\Http\Request $request
  17. * @param \Closure $next
  18. * @return mixed
  19. */
  20. public function handle(Request $request, Closure $next)
  21. {
  22. $ip = $request->getClientIp();
  23. $maxRequestsPerSecond = $this->maxRequestsPerSecond;
  24. // 使用 Redis 存储每秒请求的计数,键的格式:qps:{IP}:{timestamp_second}
  25. $redisKey = 'qps:' . $ip . ':' . now()->timestamp;
  26. // Redis 的计数器操作:INCR命令返回自增后的值
  27. $requests = Redis::incr($redisKey);
  28. // 如果是第一次请求,设置过期时间为1秒
  29. if ($requests === 1) {
  30. Redis::expire($redisKey, 1);
  31. }
  32. // 判断当前秒内请求数是否超过限制
  33. if ($requests > $maxRequestsPerSecond) {
  34. BlackList::addIp($ip);
  35. return response()->json([
  36. 'code' => 0,
  37. 'msg' => '请求频繁'
  38. ], Response::HTTP_TOO_MANY_REQUESTS);
  39. }
  40. return $next($request);
  41. }
  42. }