mvdstam/graceful-laravel-workers

此包已被弃用且不再维护。未建议替代包。

提供了一种优雅地停止 Laravel 工作进程(和工作任务)的方法。

1.0.0 2017-01-12 14:26 UTC

This package is not auto-updated.

Last update: 2023-12-19 20:51:34 UTC


README

优雅地停止你的工作进程和工作任务,而不会伤害你的应用程序。

在许多现代网络应用程序中,许多任务通过使用某种类型的队列系统和任务来异步处理。在 Laravel 和 Lumen 基础的应用程序中,这可以通过使用 illuminate/queue 组件来实现。此包通过使用 Posix 信号 使得优雅地停止工作进程(或任何类型的进程)成为可能。这也使得你的队列工作进程可以在 Docker 容器 中运行,并以优雅且干净的方式停止,因为 Docker 利用 Posix 信号在例如更新容器时停止正在运行的容器。

最终,优雅地清理运行中的进程是任何 12 因素应用 的重要组成部分。

为什么这很重要?

当通过 php artisan queue:work --daemon 启动队列工作进程时,会启动一个 长时间运行的 PHP 进程。此进程将无限期地运行,直到它被外部来源(posix 信号)或内部来源(进程崩溃或简单地因为 exit; 停止)停止。

通常,这些 PHP 进程通过向底层进程发送 SIGTERMSIGINT 信号来外部停止。PHP 的默认行为是立即停止进程,这意味着任何重要的进程都会被中断,并且可能会丢失数据。通过使用 PCNTL 扩展来 捕获 这些信号,我们可以在发生这种情况时定义自定义行为。这对于在 Docker 容器中运行队列工作进程特别有趣,因为容器是设计成短暂的,并且可以(应该)随时替换。

shutting_down()

此包最重要的方面是函数 shutting_down()。在你的长时间运行的任务中,只需在每个迭代中调用 shutting_down()。当捕获到信号时,此函数返回 TRUE,此时你的应用程序应准备立即关闭。例如

<?php

use function Mvdstam\GracefulLaravelWorkers\shutting_down;

class MyJob implements \Illuminate\Contracts\Queue\ShouldQueue {

    use \Illuminate\Queue\InteractsWithQueue, \Illuminate\Bus\Queueable;

    public function handle()
    {
        while(true) {
            if (shutting_down()) {
                return $this->shutDown();
            }

            $this->handleIteration();
        }
    }

    protected function shutDown()
    {
        // Do some kind of cleaning up, write to log, etc..
        echo 'Saving state and shutting down!';

        /*
         * Sometimes, this job may be continued later on if necessary. Simply dispatch a new instance
         * unto the queue to be picked up later.
         */
        dispatch(new static);
    }

    protected function handleIteration()
    {
        // Do something expensive, such as working on large data sets
    }
}

版本兼容性

此包与 Lumen/Laravel 5.1 (LTS) 和 Lumen/Laravel 5.2 兼容。截至编写时,不支持版本 5.3。

要求

安装

通过 composer

$ composer require mvdstam/graceful-laravel-workers

GracefulLaravelWorkersServiceProvider 添加到你的 app.php

        [..]
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,

        /*
         * Package Service Providers
         */
        Mvdstam\GracefulLaravelWorkers\Providers\GracefulLaravelWorkersServiceProvider::class,

为了正确初始化包,请确保在Illuminate\Queue\QueueServiceProvider之后添加GracefulLaravelWorkersServiceProvider

最后,运行php artisan vendor:publish

用法

使用php artisan queue:work --daemon启动工作进程,并在它获取一个任务时尝试发送SIGINTSIGTERM信号。当进程在前台运行时,只需按下ctrl+c即可发送SIGINT

注意事项

  • 始终以--daemon标志运行队列工作进程。此包仅在守护进程模式下运行时才扩展队列工作进程的行为。
  • 在完成清理后,不要在任务中使用exit;。只需从handle()函数返回,并让Worker停止进程。这允许您的应用程序有一个一致的入口点以及退出点。