【Laravel-海贼王系列】第二十章, 精通 Horizon 之后可以为所欲为(下)

2,117 阅读2分钟

管理进程 & 工作进程

时隔大半年了,把上一章最后进程管理的部分完善了一下,最后进程管理的部分非常精彩!

这次接着【Laravel-海贼王系列】第十九章, 精通 Horizon 之后可以为所欲为(上) 结束的部分,在我们启动了进程之后,

查看系统中当前运行的进程图

工作进程源码

主要关注 horizon:work 进程,因为这是主要的工作进程,下面是源码
 <?php
 
 namespace Laravel\Horizon\Console;
 
 use Illuminate\Queue\Console\WorkCommand as BaseWorkCommand;
 
 class WorkCommand extends BaseWorkCommand
 {
     /**
      * The console command name.
      *
      * @var string
      */
     protected $signature = 'horizon:work
                             {connection? : The name of the queue connection to work}
                             {--delay=0 : Amount of time to delay failed jobs}
                             {--daemon : Run the worker in daemon mode (Deprecated)}
                             {--force : Force the worker to run even in maintenance mode}
                             {--memory=128 : The memory limit in megabytes}
                             {--once : Only process the next job on the queue}
                             {--stop-when-empty : Stop when the queue is empty}
                             {--queue= : The names of the queues to work}
                             {--sleep=3 : Number of seconds to sleep when no job is available}
                             {--supervisor= : The name of the supervisor the worker belongs to}
                             {--timeout=60 : The number of seconds a child process can run}
                             {--tries=0 : Number of times to attempt a job before logging it failed}';
 
     /**
      * Indicates whether the command should be shown in the Artisan command list.
      *
      * @var bool
      */
     protected $hidden = true;
 
     /**
      * Execute the console command.
      *
      * @return void
      */
     public function handle()
     {
         if (config('horizon.fast_termination')) {
             ignore_user_abort(true);
         }
 
         parent::handle();
     }
 }

工作进程父类源码

parent::handle();

parent::handle() 实际上执行了 Laravel 的 WorkCommand 构造函数

这里可以看出 Horizon 实际上是用了 Laravelqueue:work 的代码,这是人干的事儿么~

这里要注意一些区别,这里面的用了 queue:work 的代码,而不是直接调用 php artisan queue:work,

这也就是为什么我们在进程中看的的名字不包含 queue:work 而是 horizon:work,但是却能实现 Laravel 提供的

的队列消费功能,到了这里分析的其实不是 Horizon Work 了,应该分析 queue:work 的逻辑了~其实 Horizon

內容从这里开始就已经结束了,接下来额外看看 Laravel 是怎么实现队列的把。

WorkCommand 執行逻辑

    /**
     * Execute the console command.
     *
     * @return void
     */
     
    public function handle()
    {
        if ($this->downForMaintenance() && $this->option('once')) {
            return $this->worker->sleep($this->option('sleep'));
        }

        // Well listen to the processed and failed events so we can write information
        // to the console as jobs are processed, which will let the developer watch
        // which jobs are coming through a queue and be informed on its progress.
        $this->listenForEvents();

        $connection = $this->argument('connection')
                        ?: $this->laravel['config']['queue.default'];

        // We need to get the right queue for the connection which is set in the queue
        // configuration file for the application. We will pull it based on the set
        // connection being run for the queue operation currently being executed.
        $queue = $this->getQueue($connection);


        // '啥也不管,直接进入主题,传入连接和队列名称,执行'
        $this->runWorker(
            $connection, $queue
        );
    }
    

意外

正当我准备大干一场,深入浅出的分析 queue:work 源码的时候,突然有个灵感来袭, 我仿佛写过一篇文章,惊呼一声,握草!差点写重了~

【Laravel-海贼王系列】第十一章,Job&队列消费端实现

总结

哈哈,这章有点意思,核心还是 horizon:work 使用 queue:work 的源码。

但是 Horizon 更多的是提供了強大的 Worker 进程管理,动态缩放进程,友好的 UI,

以及简单的维护命令等待,唯一的缺点就是无法支持 Redis 集群。