我看到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;

推荐答案

大多数人在supervisord个设置中运行他们的队列工作程序,这有一些缺点,比如不支持延迟启动(除非你添加一个带睡眠的脚本),并且无法处理致命的崩溃,这意味着队列工作程序将崩溃,主管不会重新启动它(见过你的队列填满吗?:)

有一个我刚刚开始使用的解决方案,将下面的脚本作为php-fpm docker-tainer的CMD运行.

优势:

  • 不需要向php-fpm容器添加Superord(节省大量资源)
  • 队列肯定会在出现故障时重新启动
  • 可以通过捕获信号来处理自动扩展事件期间的正常关闭
  • 它简单而高效
#!/usr/bin/env bash

export work=true

function stopQueues() {
    echo "Stopping queues..."
    work=false
    php artisan queue:restart
    sleep 300
    exit 0
}

# handle graceful shutdown
trap "" SIGPIPE
trap stopQueues SIGTERM SIGINT SIGHUP

echo "Starting PHP queue workers..."
# SQS_QUEUE (bg)
(while work; do
    php artisan queue:work --queue="$(grep -oP 'SQS_QUEUE=\K.*' .env)" --no-interaction
    sleep 1
done &)

# SQS_FALLBACK_QUEUE (bg)
(while work; do
    php artisan queue:work --queue="$(grep -oP 'SQS_FALLBACK_QUEUE=\K.*' .env)" --no-interaction
    sleep 1
done &)

# SQS_NOTIFICATION_QUEUE (fg) blocking
while work; do
    php artisan queue:work --queue="$(grep -oP 'SQS_NOTIFICATION_QUEUE=\K.*' .env)" --no-interaction
    sleep 1
done

Laravel相关问答推荐

警告:构建Reaction App(VITE)后无法解码下载的字体警告

密码确认在Livewire中不匹配

在postgres/mysqlс中,我可以定义基于json字段的唯一索引吗?

laravel vue 惯性分页器删除上一个和下一个链接

按回车键时如何防止此功能运行?

laravel 如何验证跨越午夜的两个值之间的时间(15:00 > 时间 > 01:00)

Laravel Eloquent 查找日期超过 2 天的行

Laravel 5.1 - 如何在进度条上设置消息

Laravel Blade 模板 @foreach 订单

限制 Blade foreach 循环中的结果

合并和排序两个 Eloquent 集合?

在 Laravel 中下载后如何重定向?

如果值存在于另一个字段数组中,Laravel 验证规则

扩展模型 == 扩展 Eloquent?

Laravel Socialite 在本地主机上进行测试,SSL 证书问题?

在 Laravel 应用程序中在哪里指定应用程序版本?

在 laravel Passport 客户端应用程序中使用访问令牌获取用户数据

Laravel 部署……有标准的方式吗?

带有 Xdebug 的 Laravel 5 总是抛出The payload is invalid..

如何从 laravel 5.1 中数据库表的 created_at 属性中 Select 年份和月份?