webman限流器,支持注解限流。
支持apcu、redis、memory驱动。
https://github.com/webman-php/rate-limiter
composer require webman/rate-limiter
<?php
namespace app\controller;
use RuntimeException;
use Webman\RateLimiter\Annotation\RateLimiter;
use Webman\RateLimiter\Limiter;
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 '每个用户60秒最多100次搜索';
}
#[RateLimiter(limit: 1, ttl: 60, key: RateLimiter::SID, message: '每人每分钟只能发1次邮件')]
public function sendMail(): string
{
// key: RateLimiter::SID,以session_id为维度进行限流
return '邮件发送成功';
}
#[RateLimiter(limit: 100, ttl: 24*60*60, key: 'coupon', message: '今天的优惠券已经发完,请明天再来')]
#[RateLimiter(limit: 1, ttl: 24*60*60, key: RateLimiter::UID, message: '每个用户每天只能领取一次优惠券')]
public function coupon(): string
{
// key: 'coupon', 这里coupon为自定义key,也就是全局以coupon为key进行限流,每天最多发100张优惠券
// 同时以用户ID为维度进行限流,每个用户每天只能领取一次优惠券
return '优惠券发送成功';
}
public function sendSms(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 sendSms2(): string
{
// 当key为变量时,可以使用[类, 静态方法]的方式获取key,例如[UserController::class, 'getMobile']会调用UserController的getMobile()方法的返回值为key
return '短信发送成功';
}
/**
* 自定义key,获取手机号,必须是静态方法
* @return string
*/
public static function getMobile(): string
{
return request()->get('mobile');
}
#[RateLimiter(limit: 1, ttl: 10, key: RateLimiter::IP, message: '频率受限', exception: RuntimeException::class)]
public function testException(): string
{
// 超限默认异常为Webman\RateLimiter\RateLimitException,可以通过exception参数更改
return 'ok';
}
}
说明
ttl:60
为60秒127.0.0.1
不限流,参见下面配置部分)session('user.id')
不为空),SID限流(根据session_id
限流)X-Forwarded-For
头,参见nginx代理Webman\RateLimiter\RateLimitException
异常,可通过exception:xx
来自定义异常类Too Many Requests
,可通过message:xx
自定义错误信息composer require symfony/translation
mkdir resource/translations/zh_CN/ -p
echo "<?php
return [
'Too Many Requests' => '请求频率受限'
];" > resource/translations/zh_CN/messages.php
php start.php restart
config/plugin/webman/rate-limiter/app.php
<?php
return [
'enable' => true,
'driver' => 'auto', // auto, apcu, memory, redis
'stores' => [
'redis' => [
'connection' => 'default',
]
],
// 这些ip的请求不做频率限制(只有在key为 RateLimiter::IP 时有效)
'ip_whitelist' => [
'127.0.0.1',
],
];
auto
apcu
memory
redis
中的一个值,使用auto
时会自动在apcu
和memory
中选一个值redis
配置,connection
对应config/redis.php
中对应的key
RateLimiter::IP
时有效)memory
介绍
无需安装任何扩展,性能最好。
使用限制
限流只对当前进程有效,多个进程间不共享限流数据,同时也不支持集群限流。
试用场景
windows开发环境;不需要严格限流的业务;抵御CC攻击时。
apcu
安装扩展
当driver使用apcu时,需要安装apcu扩展,并且php.ini中设置
apc.enabled=1
apc.enable_cli=1
如果不知道php.ini位置,可以通过命令php --ini
寻找php.ini的位置
介绍
性能略低于memory,支持多进程共享限流数据。
使用限制
不支持集群
使用场景
任何开发环境;线上单机限流场景;集群不需要严格限流的场景;抵御CC攻击。
redis
依赖
需要安装redis扩展,并安装Redis组件,安装命令
composer require -W illuminate/redis illuminate/events
介绍
性能低于apcu,支持单机也支持集群精确限流
适用场景
开发环境;线上单机环境;集群环境
Hhh
大佬~ “试用场景、使用场景、适用场景”?🤭
大赞
老大V5
6666 就喜欢这个扩展
支持一下
赞👍