Pom*_*oma 5 php laravel laravel-5.5
我有一个将请求发送到远程服务的队列。有时,此服务需要维护。当遇到这种情况时,我希望所有队列任务暂停并在10分钟后重试。我该如何实施?
您可以使用Queue::looping()事件侦听器暂停整个队列或连接(而不仅仅是单个作业类)。与其他方法不同,这不会在队列暂停时将每个作业置于弹出/重新排队的循环中,这意味着尝试次数不会增加。
这是文档所说的:
使用Facade
looping上的方法Queue,您可以指定在 worker 尝试从队列中获取作业之前执行的回调。
这并没有很好地记录的是,如果回调返回,false那么工作人员将不会获取另一个工作。例如,这将阻止default队列运行:
Queue::looping(function (\Illuminate\Queue\Events\Looping $event) {
// $event->connectionName (e.g. "database")
// $event->queue (e.g. "default")
if ($event->queue == 'default') {
return false;
}
});
Run Code Online (Sandbox Code Playgroud)
注意:queue当工作进程启动时,事件的属性将包含来自命令行的值,因此如果您的工作人员正在检查多个队列(例如artisan queue:work --queue=high,default),则queue事件中的值将是'high,default'。作为预防措施,您可能希望用逗号分隔字符串并检查是否default在列表中。
因此,例如,如果您想创建一个基本的断路器以mail在邮件服务返回维护错误时暂停队列,那么您可以在EventServiceProvider.php 中注册这样的侦听器:
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
Queue::looping(function (\Illuminate\Queue\Events\Looping $event) {
if (($event->queue == 'mail') && (cache()->get('mail-queue-paused'))) {
return false;
}
});
}
Run Code Online (Sandbox Code Playgroud)
这假设您在应用程序的其他地方有一种机制来检测适当的情况,在本例中,该机制需要为mail-queue-paused共享缓存中的键分配一个值(因为这是我的代码正在检查的内容)。有更强大的解决方案,但在缓存中设置一个特定的众所周知的键(并自动使其过期)很简单并且可以达到预期的效果。
<?php
namespace App\Jobs;
use ...
class SendRequest implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
const REMOTE_SERVER_UNAVAILABLE = 'remote_server_unavailable';
private $msg;
private $retryAfter;
public function __construct($msg)
{
$this->msg = $msg;
$this->retryAfter = 10;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(){
try {
// if we have tried sending the request and get a RemoteServerException, we will
// redispatch the job directly and return.
if(Cache::get(self::REMOTE_SERVER_UNAVAILABLE)) {
self::dispatch($this->msg)->delay(Carbon::now()->addMinutes($this->retryAfter));
return;
}
// send request to remote server
// ...
} catch (RemoteServerException $e) {
// set a cache value expires in 10 mins if not exists.
Cache::add(self::REMOTE_SERVER_UNAVAILABLE,'1', $this->retryAfter);
// if the remote service undergoes a maintenance, redispatch a new delayed job.
self::dispatch($this->msg)->delay(Carbon::now()->addMinutes($this->retryAfter));
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1190 次 |
| 最近记录: |