<?php
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;
class RedisRateLimited
{
/**
* Uses Redis to throttle the execution of a job.
*
* @param int $allow count of jobs you wish to allow to execute
* @param int $every period of time in seconds
*/
public function __construct(protected int $allow, protected int $every)
{}
/**
* Process the queued job.
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
Redis::throttle('your-key-here')
->block(0)->allow($this->allow)->every($this->every)
->then(function () use ($job, $next) {
// Lock obtained...
$next($job);
}, function () use ($job) {
// Could not obtain lock...
$job->release(5);
});
}
}
然后将其附加到相关作业,如下所示:
/**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [new RedisRateLimited(allow: 1, every: 1)];
}
6条答案
按热度按时间xsuvu9jc1#
我是mxl/laravel-queue-rate-limit Composer软件包的作者。
它允许你在不使用Redis的情况下对特定队列中的作业进行速率限制。
1.安装时:
1.此软件包与Laravel 5.5+兼容,并使用auto-discovery功能将
MichaelLedin\LaravelQueueRateLimit\QueueServiceProvider::class
添加到提供程序。1.将速率限制设置添加到
config/queue.php
:这些设置允许在
mail
队列上每5秒运行1个作业。请确保默认队列驱动程序(config/queue.php
中的default
属性)设置为除sync
之外的任何值。1.使用
--queue mail
选项运行队列工作进程:您可以在多个队列上运行工作进程,但只有
rateLimit
设置中引用的队列才受速率限制:default
队列上的作业将在没有速率限制的情况下执行。1.将一些作业排队以测试速率限制:
ncecgwcz2#
假设您只有一个工人,您可以执行以下操作:
所以基本上
4c8rllxm3#
如果你需要“节流”并且没有使用Redis作为队列驱动程序,你可以尝试使用下面的代码:
这段代码所做的是释放一个作业到队列中,并将开始时间设置为最后一个调度作业的开始时间之后X秒。我用数据库作为队列驱动程序,文件作为缓存驱动程序成功地测试了这一点。
到目前为止我遇到了两个小问题:
1)当您仅使用1秒作为延迟时,这取决于您的队列工作进程-队列工作进程实际上可能每隔几秒才“唤醒”一次。因此,如果它每3秒唤醒一次,则它将同时执行3个作业,然后再次“休眠”3秒。但是平均您仍将每秒仅执行一个作业。
2)在Laravel 5.7中,不可能使用Carbon将作业延迟设置为小于一秒,因为它还不支持毫秒或微秒。这在Laravel 5.8中应该是可能的-只需使用
addMilliseconds
而不是addSeconds
。9fkzdhlc4#
spatie/laravel-rate-limited-job-middleware
如果你使用的是Laravel 6或更高版本,这是一个很好的包。好的是你可以在作业中配置中间件。
安装
第一个月
dzhpxtsq5#
我最近也遇到了同样的问题,Laravel的开箱即用的作业速率限制器不允许你设置每秒的执行限制。
我通过编写一个定制的作业中间件来处理它,如下所示:
然后将其附加到相关作业,如下所示:
jei2mxaa6#
你可以用这个包来限制Redis或其他资源的速率,比如文件。使用设置来设置桶的大小和速率作为时间限制的分数,所以存储空间非常小。
https://github.com/bandwidth-throttle/token-bucket
它允许你用if来 Package 检查,所以它会等待一个免费的令牌可用,在你的例子中是每分钟1个,实际上,它使服务休眠所需的时间,直到一个新的分钟。