webman限流器,支持注解限流。 支持apcu、redis、memory驱动。
composer require webman/rate-limiter
<?php
namespace app\controller;
use Webman\RateLimiter\Annotation\RateLimiter;
use Webman\RateLimiter\Limiter;
/**
* test-users
*/
class UserController
{
#[RateLimiter(limit: 10)]
public function index(): string
{
// 默认为IP限流,默认单位时间为1秒
return '每个ip每秒最多10个请求';
}
#[RateLimiter(limit: 100, ttl: 60, key: RateLimiter::UID)]
public function search(): string
{
// key: RateLimiter::UID,以用户ID为维度进行限流,要求session('user.id')不为空
return '每个用户每分钟最多100次搜索';
}
#[RateLimiter(limit: 1, ttl: 60, key: RateLimiter::SID, message: '每人每分钟只能发一次邮件')]
public function sendMail(): string
{
// key: RateLimiter::SID,以session_id为维度进行限流
return '每人每分钟只能发一次邮件';
}
#[RateLimiter(limit: 100, ttl: 24 * 60 * 60, key: 'coupon', message: '今天的优惠券已经发完,请明天再来')]
public function coupon(): string
{
// key: 'coupon', 这里coupon为自定义key,也就是全局以coupon为key进行限流
return '优惠券发送成功';
}
public function sendCms(string $mobile): string
{
// 当key为变量时,可以使用如下代码手动限流,这里mobile作为key
Limiter::check($mobile, 5, 24 * 60 * 60, '每个手机号一天最多5条短信');
return '短信发送成功';
}
#[RateLimiter(limit: 5, ttl: 24 * 60 * 60, key: [UserController::class, 'getMobile'], message: '每个手机号一天最多5条短信')]
public function sendCms2(): string
{
// 当key为变量时,可以使用[类, 方法]的方式获取key,例如[UserController::class, 'getMobile']会调用UserController的getMobile()方法的返回值为key
return '短信发送成功';
}
/**
* 自定义key,获取手机号
* @return string
*/
public static function getMobile(): string
{
return request()->get('mobile');
}
}
开源技术小栈config/plugin/webman/rate-limiter/app.php
<?php
return [
'enable' => true,
'driver' => 'auto', // auto, apcu, memory, redis
'stores' => [
'redis' => [
'connection' => 'default',
]
],
// 这些ip的请求不做频率限制
'ip_whitelist' => [
//'127.0.0.1',
],
];
auto
,apcu
,memory
,redis
中的一个值,使用auto
时会自当在apcu
和redis
中选一个值connection
对应config/redis.php
中对应的值RateLimiter::IP
时有效)driver
使用apcu
时,需要安装apcu
扩展,并且php.ini
中设置apc.enabled=1
apc.enable_cli=1
如果不知道php.ini
位置,可以通过命令php --ini
寻找php.ini
的位置
composer require -W illuminate/redis illuminate/events