当前位置:首页 > PHP

php 实现网关限流

2026-02-15 15:18:30PHP

PHP 实现网关限流的方法

令牌桶算法实现

令牌桶算法是一种常用的限流方法,通过控制令牌的生成和消耗来实现限流。以下是一个简单的 PHP 实现:

class TokenBucket {
    private $capacity;
    private $tokens;
    private $lastTime;

    public function __construct($capacity) {
        $this->capacity = $capacity;
        $this->tokens = $capacity;
        $this->lastTime = time();
    }

    public function consume($tokens = 1) {
        $now = time();
        $elapsed = $now - $this->lastTime;
        $this->tokens = min($this->capacity, $this->tokens + $elapsed);
        $this->lastTime = $now;

        if ($this->tokens >= $tokens) {
            $this->tokens -= $tokens;
            return true;
        }
        return false;
    }
}

// 使用示例
$bucket = new TokenBucket(10); // 每秒最多10个请求
if (!$bucket->consume()) {
    http_response_code(429);
    exit('Too Many Requests');
}

漏桶算法实现

漏桶算法以固定速率处理请求,超出容量的请求会被丢弃或排队。PHP 实现如下:

class LeakyBucket {
    private $capacity;
    private $rate;
    private $water;
    private $lastTime;

    public function __construct($capacity, $rate) {
        $this->capacity = $capacity;
        $this->rate = $rate;
        $this->water = 0;
        $this->lastTime = time();
    }

    public function add() {
        $now = time();
        $leaked = ($now - $this->lastTime) * $this->rate;
        $this->water = max(0, $this->water - $leaked);
        $this->lastTime = $now;

        if ($this->water < $this->capacity) {
            $this->water++;
            return true;
        }
        return false;
    }
}

// 使用示例
$bucket = new LeakyBucket(10, 1); // 容量10,每秒漏出1个
if (!$bucket->add()) {
    http_response_code(429);
    exit('Rate Limit Exceeded');
}

Redis 分布式限流

对于分布式系统,可以使用 Redis 实现限流:

function checkRateLimit($key, $limit, $window) {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);

    $current = $redis->get($key);
    if ($current && $current >= $limit) {
        return false;
    }

    $redis->multi();
    $redis->incr($key);
    $redis->expire($key, $window);
    $redis->exec();
    return true;
}

// 使用示例
if (!checkRateLimit('user:123', 100, 60)) { // 每分钟100次
    http_response_code(429);
    exit('Rate Limit Exceeded');
}

Nginx 层限流

在网关层面可以使用 Nginx 的 limit_req 模块:

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=mylimit burst=20 nodelay;
            proxy_pass http://backend;
        }
    }
}

中间件实现

在框架中可以使用中间件实现限流,例如 Laravel:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Cache\RateLimiter;
use Symfony\Component\HttpFoundation\Response;

class ThrottleRequests {
    protected $limiter;

    public function __construct(RateLimiter $limiter) {
        $this->limiter = $limiter;
    }

    public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1) {
        $key = $request->ip();

        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            return new Response('Too Many Attempts', 429);
        }

        $this->limiter->hit($key, $decayMinutes * 60);
        return $next($request);
    }
}

限流策略选择建议

  • 对于简单应用,可以使用 PHP 内存实现的令牌桶或漏桶算法
  • 分布式系统推荐使用 Redis 实现
  • 高性能场景建议在 Nginx 层实现限流
  • 框架应用可以使用内置的限流中间件

每种方法都有其适用场景,应根据具体需求选择合适的限流策略。

php 实现网关限流

标签: 网关php
分享给朋友:

相关文章

php实现文件下载

php实现文件下载

PHP实现文件下载的方法 通过PHP实现文件下载功能,可以采用多种方式,以下是几种常见的实现方法: 使用header()函数强制下载 设置HTTP头信息,强制浏览器下载文件而非直接打开:…

php实现图片上传

php实现图片上传

实现图片上传的基本步骤 创建HTML表单用于文件上传,表单需设置enctype="multipart/form-data"属性,确保文件数据正确传输。 <form action="uploa…

php实现增删改查

php实现增删改查

以下是在PHP中实现增删改查(CRUD)操作的详细方法,以MySQL数据库为例: 数据库连接配置 创建config.php文件存储数据库连接信息: <?php $host = 'loca…

php实现

php实现

PHP 实现的基本方法 PHP 是一种服务器端脚本语言,广泛用于 Web 开发。以下是 PHP 实现的一些常见方法。 变量与数据类型 PHP 变量以 $ 开头,支持多种数据类型: $n…

php 实现购物车

php 实现购物车

PHP 实现购物车功能 购物车功能是电子商务网站的核心部分,可以通过 PHP 和 Session 或数据库来实现。以下是两种常见的实现方式: 使用 Session 存储购物车数据 Sessi…

php实现文件的下载

php实现文件的下载

PHP 实现文件下载的方法 在 PHP 中实现文件下载功能通常需要设置正确的 HTTP 头信息,并输出文件内容。以下是几种常见的实现方式: 使用 header() 函数强制下载 通过设置 Conte…