当前位置:首页 > 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 实现如下:

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 实现限流:

php 实现网关限流

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中实现验证码功能通常涉及生成随机字符串或数字,将其转换为图像,并通过会话(Session)进行验证。以下是几种常见的实现方式: 使用GD库生成图像验证码 GD库是PHP内置的…

php 实现队列

php 实现队列

PHP 实现队列的方法 PHP 可以通过多种方式实现队列功能,以下是几种常见的实现方法: 使用数组实现队列 PHP 数组可以通过 array_push 和 array_shift 函数模拟队列的先进…

php 实现无限分类

php 实现无限分类

无限分类的实现方法 无限分类通常用于构建多层级结构的数据,如商品分类、菜单管理等。以下是几种常见的实现方式: 邻接列表模型(Adjacency List) 这是最简单的实现方式,每个分类记录存储其父…

php 实现链表

php 实现链表

PHP 实现链表的方法 链表是一种线性数据结构,由节点组成,每个节点包含数据和指向下一个节点的指针。PHP 中可以通过类和对象来实现链表。 定义链表节点类 创建一个 ListNode 类,用于表示链…

php 实现md5

php 实现md5

使用 PHP 内置函数实现 MD5 PHP 提供了 md5() 函数,可以直接计算字符串的 MD5 哈希值。该函数接受一个字符串参数,返回 32 字符的十六进制哈希值。 $string = "H…

php 实现路由

php 实现路由

PHP 实现路由的方法 在 PHP 中实现路由功能可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 PHP 实现简单路由 通过解析 URL 并匹配对应的处理逻辑,可以实现基本的路由功能。以…