我看到Laravel 8、9、10处理SIGTERM信号上的队列工作人员.但是根据Worker类的下面的注释(在第185行上的Worker.php),laravel只在当前的Worker执行中处理它,如果supervisor(或使用的其他监视工具)没有被更改为考虑到该SIGTERM并且不再启动Worker,那么它几乎没有什么影响,因为Worker在他finishes执行之后被从laravel中停止.(也可以在管理程序停止重新启动队列时发出Restart,以便所有作业(job)被优雅地停止).
// Finally, we will check to see if we have exceeded our memory limits or if
// the queue should restart based on other indications. If so, we'll stop
// this worker and let whatever is "monitoring" it restart the process.
日程表怎么样?如果收到SIGTERM信号,我如何阻止(从Laravel内部)\App\Console\Kernel::Schedule函数启动命令?
基本上
php artisan schedule:run
在SIGTERM信号之后应该什么都不做.
当 docker 集装箱关闭时,它会收到这个信号.我想阻止该容器上的任何新的预定命令开始.这发生在部署或缩减方案中.我不希望集装箱在过程中被杀死.
行政协调会.设置为https://stackoverflow.com/a/53733389/7309871(如果自2018年以来没有任何变化),在队列中运行命令将解决此问题,但会将调度程序仅限于作业(job).
由于拉威尔使用的是symfony https://symfony.com/blog/new-in-symfony-5-2-console-signals
如果您希望为所有应用程序命令处理一些信号 (例如,记录或分析命令)、定义事件侦听器或 订阅服务器并监听新的ConsoleEvents::Signal事件.
但这无论如何都不能处理它,因为:
对于内核来说,这可能是一种可能的解决方案,但因为它的执行窗口非常窄,并且因为这是在每一分钟缺少在秒30发送的SIGTERM而执行的,所以更好的方法是在接收到SIGTERM信号之后停止执行php artisan schedule:run
服务器端.
\App\Console\Kernel.php
/**
* @inheritdoc
*/
public function __construct(Application $app, Dispatcher $events)
{
parent::__construct($app, $events);
$this->app->singleton(SignalSingleton::class);
if (!\extension_loaded('pcntl')) {
return;
}
\pcntl_async_signals(true);
\pcntl_signal(SIGTERM, function (int $signo, mixed $siginfo): void {
Log::info('SIGTERM received');
\resolve(SignalSingleton::class)->shedulerIsEnabled = false;
});
}
/**
* Define the application's command schedule.
*/
protected function schedule(Schedule $schedule): void
{
if (!\resolve(SignalSingleton::class)->shedulerIsEnabled) {
return;
}
...
The SignalSingleton class should contain only a public bool $shedulerIsEnabled = true;