cjphp / rate-limiter
php限流器,支持文件/Redis 存储与固定窗口、滑动窗口、漏桶策略
v1.0.0
2024-05-17 15:25 UTC
Requires
- php: >=8.1
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-28 00:18:15 UTC
README
基于 PHP 8.1+ 的限流组件,支持文件 / Redis 存储,以及固定窗口、滑动窗口、漏桶策略。
特性
存储方式
- 文件存储(单机,目录自动创建)
- Redis 存储(多机可用,通过分布式锁保证并发安全)
流控策略
- 固定窗口策略(窗口交界处可能出现接近 2 倍限额的突发,属算法固有特性)
- 滑动窗口策略
- 漏桶策略
并发与失败策略
- 策略判定在存储层互斥锁内执行,避免 read-modify-write 竞态超额放行
- 抢锁或存储异常时采用失败关闭(fail-closed):视为触发限流,避免绕过
项目结构
rate-limiter/
├── src/
│ ├── RateLimiter.php
│ ├── StorageFactory.php
│ ├── StrategyFactory.php
│ ├── Exception/
│ │ └── RateLimitException.php
│ ├── Storage/
│ │ ├── StorageInterface.php
│ │ ├── FileStorage.php
│ │ └── RedisStorage.php
│ └── Strategy/
│ ├── StrategyInterface.php
│ ├── FixedWindowStrategy.php
│ ├── SlidingWindowStrategy.php
│ └── LeakyBucketStrategy.php
├── tests/
├── composer.json
├── phpunit.xml
└── README.md
安装
composer require cjphp/rate-limiter:~1.0
使用 Redis 存储时需安装 ext-redis(phpredis)。
使用方法
use RateLimiter\RateLimiter; use RateLimiter\StorageFactory; use RateLimiter\StrategyFactory; $key = 'user_123'; $storeType = 'file'; // file | redis $strategyType = 'fixed_window'; // fixed_window | sliding_window | leaky_bucket $params = [ 'limit' => 10, // 窗口内最大请求数(固定/滑动窗口) 'window' => 60, // 窗口大小,秒 'rate' => 1, // 漏桶:每秒漏出 1 个请求 'capacity' => 3, // 漏桶:桶容量 3 ]; $ext = match ($storeType) { 'file' => sys_get_temp_dir() . '/ratelimit', 'redis' => $redis, // \Redis 已连接实例 }; $storage = StorageFactory::create($storeType, $ext); $strategy = StrategyFactory::create($strategyType, $storage, $params); // 注意:RateLimiter 与 Strategy 必须使用同一 $storage 实例 $rateLimiter = new RateLimiter($storage, $strategy); if ($rateLimiter->isRateLimited($key, false)) { echo '不好意思,您被流控了'; } else { echo '允许通行'; }
返回值约定
isRateLimited() 返回 true 表示触发限流(拦截),false 表示放行。
全局限流
第二个参数 $isGlobal = true 时,忽略业务 key,所有调用共享同一计数器。
开发与测试
composer install
composer test
注意事项
- 未知存储类型 / 策略类型会抛出异常,不再静默降级。
- Redis 存储会为状态 key 设置 TTL,降低长期堆积风险。
- 滑动窗口会保存窗口内时间戳列表,极高 QPS 场景需评估存储体积。