RateLimiter
是一个用于限制请求频率的PHP库。它支持多种存储后端(如Redis和数据库,比如 Sqlite),并提供不同的限流策略(如令牌桶策略)。本项目旨在帮助开发者轻松实现请求限流功能。
并且实现动态配置,如果结合配置中心,可以实现实时调整限流策略。
/Users/bytedance/php/RateLimiter/
├── composer.json
├── src/
│ ├── Storage/
│ │ ├── MemoryStorage.php
│ │ ├── RedisStorage.php
│ │ ├── SqliteStorage.php
│ │ └── StorageInterface.php
│ ├── Strategies/
│ │ ├── LeakyBucketStrategy.php
│ │ └── StrategyInterface.php
│ │ ├── TokenBucketStrategy.php
│ ├── config.json
│ └── ConfigRateLimiter.php
│ ├── DatabaseConnection.php
│ ├── RateLimiter.php
│ ├── RateLimiterInterface.php
│ └── TestConfigRateLimiter.php
│ └── TestPHPInfo.php
│ └── TestSqlite.php
│ └── TestRedis.php
│ └── README.md
└── vendor/
composer require bytedance/rate-limiter
-
克隆项目到本地:
git clone https://github.com/bytedance/rate-limiter.git
-
进入项目目录:
cd rate-limiter
-
安装依赖:
composer install
<?php
require '../vendor/autoload.php';
use Bytedance\RateLimiter\RateLimiter;
use Bytedance\RateLimiter\Storage\RedisStorage;
use Bytedance\RateLimiter\Strategies\TokenBucketStrategy;
use Bytedance\RateLimiter\Strategies\LeakyBucketStrategy;
// 使用Redis存
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$storage = new RedisStorage($redis);
// 使用TokenBucket策略
// $strategy = new TokenBucketStrategy();
// 使用LeakyBucketStrategy策略
$strategy = new LeakyBucketStrategy();
// 限流
$rateLimiter = new RateLimiter($strategy, $storage);
// 测试限流器
for ($i = 0; $i < 15; $i++) {
if ($rateLimiter->limit('user:123', 1, 5)) {
echo "Request $i allowed\n";
} else {
echo "Request $i denied\n";
}
sleep(1); // 模拟每秒一个请求
}
<?php
require '../vendor/autoload.php';
use Bytedance\RateLimiter\RateLimiter;
use Bytedance\RateLimiter\Storage\SqliteStorage;
use Bytedance\RateLimiter\Strategies\TokenBucketStrategy;
use Bytedance\RateLimiter\Strategies\LeakyBucketStrategy;
// 初始化SQLite存储
$storage = new SqliteStorage('/Users/bytedance/php/RateLimiter/database.sqlite');
// 使用TokenBucket策略
// $strategy = new TokenBucketStrategy();
// 使用LeakyBucketStrategy策略
$strategy = new LeakyBucketStrategy();
// 限流
$rateLimiter = new RateLimiter($strategy, $storage);
// 测试限流器
for ($i = 0; $i < 15; $i++) {
if ($rateLimiter->limit('user:123', 1, 5)) {
echo "Request $i allowed\n";
} else {
echo "Request $i denied\n";
}
sleep(1); // 模拟每秒一个请求
}
确保你的数据库中有一个名为rate_limiter
的表,结构如下:
CREATE TABLE IF NOT EXISTS rate_limiter (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
<?php
require '../vendor/autoload.php';
use Bytedance\RateLimiter\RateLimiter;
use Bytedance\RateLimiter\Storage\MemoryStorage;
use Bytedance\RateLimiter\Strategies\TokenBucketStrategy;
use Bytedance\RateLimiter\Strategies\LeakyBucketStrategy;
// 使用MemoryStorage存储
$storage = new MemoryStorage();
// 使用TokenBucket策略
$strategy = new TokenBucketStrategy();
// 使用LeakyBucketStrategy策略
// $strategy = new LeakyBucketStrategy();
// 限流
$rateLimiter = new RateLimiter($strategy, $storage);
// 测试限流器
for ($i = 0; $i < 15; $i++) {
if ($rateLimiter->limit('user:123', 1, 5)) {
echo "Request $i allowed\n";
} else {
echo "Request $i denied\n";
}
sleep(1); // 模拟每秒一个请求
}
{
"rate_limiters": [
{
"name": "global_limiter",
"strategy": "TokenBucket",
"storage": "Redis",
"limit": 1,
"interval": 5,
"key_pattern": "global_limiter"
},
{
"name": "user_limiter",
"strategy": "LeakyBucket",
"storage": "Memory",
"limit": 1,
"interval": 5,
"key_pattern": "user_limiter:{user_id}"
}
]
}
<?php
require '../vendor/autoload.php';
use Bytedance\RateLimiter\RateLimiterFactory;
// 使用示例
$factory = new RateLimiterFactory('config.json');
// $rateLimiter = $factory->createRateLimiter('user_limiter');
// $limit = $factory->getLimit('user_limiter');
// $interval = $factory->getInterval('user_limiter');
// 动态切换
$rateLimiter = $factory->createRateLimiter('global_limiter');
$limit = $factory->getLimit('global_limiter');
$interval = $factory->getInterval('global_limiter');
// 自定义限流参数
$context = ['user_id' => 123];
// 测试限流器
for ($i = 0; $i < 15; $i++) {
if ($rateLimiter->limit($context, $limit, $interval)) {
echo "Request $i allowed\n";
} else {
echo "Request $i denied\n";
}
sleep(1); // 模拟每秒一个请求
}
- PHP 7.4 或更高版本
- Redis(如果使用Redis存储)
- MySQL 或其他支持PDO的数据库(如果使用数据库存储)
欢迎贡献代码!请提交Pull Request,并确保遵循项目的编码规范。
本项目采用 MIT 许可证。详细信息请参阅 xxx 文件。 s
如有任何问题或建议,请通过 xxx 联系我们。