美文网首页laravel
2018-08-06Laravel官方扩展包——队列系统解决方案

2018-08-06Laravel官方扩展包——队列系统解决方案

作者: 扎扎瑜 | 来源:发表于2018-08-06 12:01 被阅读0次

    简介

    Horizon 为 Laravel 提供了基于 Redis 的、拥有美观后台的、代码驱动配置的队列系统。Horizon 让我们可以轻松监控队列系统的关键指标,例如任务吞吐量、运行时间和失败任务等。

    所有的队列进程配置都存放在一个单独的简单配置文件中,这样的话配置文件就可以存放到源码控制以便团队所有成员的协作。

    安装

    注:由于 Horizon 使用了异步进程信号,所以 PHP 7.1+ 以上版本才可以使用。

    composer安装Horizon命令:

    composer require laravel/horizon
    

    安装完成后,使用 Artisan 命令 vendor:publish 发布前端资源:

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

    发布好前端资源后,主配置文件就会出现在 config/horizon.php。在这个配置文件中,你可以配置队列进程选项以及每个包含目的描述的配置项,使用 Horizon 前可浏览下这个配置文件。

    balance 配置项

    Horizon 提供了三种负载均衡策略以供选择:simple、auto 和 false,simple 是默认策略,在进程之间平均分配进入任务:

    'balance' => 'simple',
    

    auto 策略基于队列当前负载调整每个队列的工作进程数量。例如,如果 notifications 队列有 1000 个等待执行的任务而 render 队列是空的,那么 Horizon 将会为 notifications 队列分配更多的工作进程直到队列为空。

    如果把 balance 选项设置为 false,就会使用默认的 Laravel 行为,也就是按照配置文件中的排列顺序处理队列。

    后台认证

    我们可以通过 /horizon 访问 Horizon 后台:

    image.png
    默认情况下,你只能在 local环境下访问这个后台。如果想要为后台定义更多的特定访问策略,需要使用 Horizon:auth 方法。auth 方法接收一个返回truefalse 的回调,从而决定用户是否可以访问 Horizon 后台。通常,我们会在 AppServiceProviderboot 方法中调用 Horizon:auth
    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Laravel\Horizon\Horizon;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
            //用户是否可以访问 Horizon 后台
            Horizon::auth(function ($request) {
                // return true / false;
            });
        }
    }
    
    运行 Horizon

    如果你已经在配置文件 config/horizon.php 中配置过工作进程,就可以使用 Artisan 命令 horizon 来启动 Horizon,该命令会启动所有配置的工作进程:

    php artisan horizon
    

    使用 Artisan 命令 horizon:pausehorizon:continue 来暂停或继续处理队列任务:

    php artisan horizon:pause
    
    php artisan horizon:continue
    

    还可以使用 Artisan 命令 horizon:terminate 来优雅地终止 Horizon 主进程 —— Horizon 会在所有当前正在执行的任务全部完成后退出:

    php artisan horizon:terminate
    
    部署 Horizon

    如果要将 Horizon 部署到线上服务器,需要配置一个进程监控来监控 php artisan horizon 命令的运行并在异常退出的情况下重启该进程。部署新代码到服务器的时候,需要终止 Horizon 主进程以便通过配置的进程监控以最新代码重启进程。如上所述,我们可以通过 Artisan 命令 horizon:terminate 优雅地终止 Horizon 主进。

    Supervisor 配置

    如果你在使用 Supervisor 进程监控来管理 horizon 进程,配置例子(按照自己的实际情况修改相应的目录信息):

    [program:horizon]
    process_name=%(program_name)s
    command=php /home/forge/app.com/artisan horizon
    autostart=true
    autorestart=true
    user=forge
    redirect_stderr=true
    stdout_logfile=/home/forge/app.com/horizon.log
    

    注:也可以考虑使用 Laravel ForgeForge 提供了 PHP 7+ 版本的服务器,并且拥有运行最新版 Laravel 应用所需的所有软件工具集。

    标签

    Horizon 允许分配"标签"到任务,包括邮件、事件广播、通知以及队列事件监听器等。实际上,Horizon 会基于附加到任务的 Eloquent 模型为大部分任务以智能的方式自动打上标签。例如,我们来看看下面这个例子:

    <?php
    
    namespace App\Jobs;
    
    use App\Video;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    
    class RenderVideo implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        /**
         * The video instance.
         *
         * @var \App\Video
         */
        public $video;
    
        /**
         * Create a new job instance.
         *
         * @param  \App\Video  $video
         * @return void
         */
        public function __construct(Video $video)
        {
            $this->video = $video;
        }
    
        /**
         * Execute the job.
         *
         * @return void
         */
        public function handle()
        {
            //
        }
    }
    

    如果任务被推送到队列时附带了一个 id1App\Video 实例,它将会自动打上 App\Video:1 的标签,这是因为 Horizon 会检查队列任务属性中的 Eloquent 模型,如果 Eloquent 模型被找到,Horizon 就会使用模型类名和主键为任务智能地打上标签:

    $video = App\Video::find(1);
    
    App\Jobs\RenderVideo::dispatch($video);
    
    手动打标签

    如果你想要手动定义某个队列对象的标签,可以在该类中定义一个 tags 方法:

    class RenderVideo implements ShouldQueue
    {
        /**
         * Get the tags that should be assigned to the job.
         *
         * @return array
         */
        public function tags()
        {
            return ['render', 'video:'.$this->video->id];
        }
    }
    
    通知

    注:在使用通知之前,需要通过 Composer 安装 guzzlehttp/guzzle 依赖。在配置 Horizon 发送短信通知前,还要回顾下 Nexmo 通知驱动的预备知识

    如果你想要在某个队列任务等待很长时间后被通知,可以使用 Horizon::routeMailNotificationsToHorizon::routeSlackNotificationsTo 以及 Horizon::routeSmsNotificationsTo 方法。你可以在 AppServiceProvider 中调用这些方法:

    Horizon::routeMailNotificationsTo('example@example.com');
    Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
    Horizon::routeSmsNotificationsTo('15556667777');
    
    配置通知等待时间下限

    你可以在配置文件 config/horizon.php 中通过修改 waits 配置项来配置每个连接/队列上的等待时间下限(秒):

    'waits' => [
        'redis:default' => 60,
    ],
    
    监控

    Horizon 提供了一个监控后台查看任务和队列的等待时间和吞吐量信息,为了获取实时信息,可以配置 HorizonArtisan 命令 snapshot 通过应用的调度器每五分钟运行一次:

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('horizon:snapshot')->everyFiveMinutes();
    }
    

    出处

    相关文章

      网友评论

        本文标题:2018-08-06Laravel官方扩展包——队列系统解决方案

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