美文网首页laravel
队列监控 Horizon

队列监控 Horizon

作者: 足迹人生2017 | 来源:发表于2018-07-17 09:40 被阅读4次

    Horizon 是 Laravel 生态圈里的一员,为 Laravel Redis 队列提供了一个漂亮的仪表板,允许我们很方便地查看和管理 Redis 队列任务执行的情况。

    使用 Composer 安装:

    $ composer require "laravel/horizon:~1.0"
    

    安装完成后,使用 vendor:publish Artisan 命令发布相关文件:

    $ php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"
    

    分别是配置文件 config/horizon.php 和存放在 public/vendor/horizon 文件夹中的 CSS 、JS 等页面资源文件。

    至此安装完毕,浏览器打开 http://larabbs.test/horizon 访问控制台:

    Horizon 是一个监控程序,需要常驻运行,我们可以通过以下命令启动:

    $ php artisan horizon
    

    安装了 Horizon 以后,我们将使用 horizon 命令来启动队列系统和任务监控,无需使用 queue:listen

    接下来我们再次尝试下发帖,发帖之前,请确保 horizon 命令处于监控状态:

    这一次多亏了 Horizon,我们可以清晰的看到更加详尽的错误信息,错误异常是 ModelNotFoundException,最重要的:

    我们发现 Data 区块里,id 的值居然为 null。我们知道的,队列系统对于构造器里传入的 Eloquent 模型,将会只序列化 ID 字段,因为我们是在 Topic 模型监控器的 saving() 方法中分发队列任务的,此时传参的 $topic 变量还未在数据库里创建,所以 $topic->id 为 null。

    6. 代码调整

    既然我们已经定位到了问题,解决的方法也很简单,只需要确保分发任务时 $topic->id 有值即可。我们需要修改任务分发的时机:

    app/Observers/TopicObserver.php

    <?php
    
    namespace App\Observers;
    
    use App\Models\Topic;
    use App\Jobs\TranslateSlug;
    
    // creating, created, updating, updated, saving,
    // saved,  deleting, deleted, restoring, restored
    
    class TopicObserver
    {
        public function saving(Topic $topic)
        {
            // XSS 过滤
            $topic->body = clean($topic->body, 'user_topic_body');
    
            // 生成话题摘录
            $topic->excerpt = make_excerpt($topic->body);
        }
    
        public function saved(Topic $topic)
        {
            // 如 slug 字段无内容,即使用翻译器对 title 进行翻译
            if ( ! $topic->slug) {
    
                // 推送任务到队列
                dispatch(new TranslateSlug($topic));
            }
        }
    }
    

    模型监控器的 saved() 方法对应 Eloquent 的 saved 事件,此事件发生在创建和编辑时、数据入库以后。在 saved() 方法中调用,确保了我们在分发任务时,$topic->id 永远有值。

    需要注意的是,artisan horizon 队列工作的守护进程是一个常驻进程,它不会在你的代码改变时进行重启,当我们修改代码以后,需要在命令行中对其进行重启操作。

    重启 horizon 命令后再次尝试:

    7. 线上部署须知

    在开发环境中,我们为了测试方便,直接在命令行里调用 artisan horizon 进行队列监控。然而在生产环境中,我们需要配置一个进程管理工具来监控 artisan horizon 命令的执行,以便在其意外退出时自动重启。当服务器部署新代码时,需要终止当前 Horizon 主进程,然后通过进程管理工具来重启,从而使用最新的代码。

    简而言之,生产环境下使用队列需要注意以下两个问题:

    1. 使用 Supervisor 进程工具进行管理,配置和使用请参照 文档 进行配置;
    2. 每一次部署代码时,需 artisan horizon:terminate 然后再 artisan horizon 重新加载代码。

    8. 使用 Sync 队列驱动

    既然功能已经开发测试完毕,为了后续开发的方便,我们将开发环境的队列驱动改回 sync 同步模式,也就是说不使用任何队列,实时执行:

    .env

    QUEUE_DRIVER=sync
    

    相关文章

      网友评论

        本文标题:队列监控 Horizon

        本文链接:https://www.haomeiwen.com/subject/hocwpftx.html