Larave Horizon 队列仪表盘

安装使用参考文档

https://learnku.com/docs/laravel/5.5/horizon/1345#configuration

本文主要记录一些使用中碰到的问题,文档有的不再赘述.

配置文件介绍

 /*
    |--------------------------------------------------------------------------
    | Horizon Redis Connection
    |--------------------------------------------------------------------------
    |
    | This is the name of the Redis connection where Horizon will store the
    | meta information required for it to function. It includes the list
    | of supervisors, failed jobs, job metrics, and other information.
    |
    */

    'use' => 'payhandle',

指定horizon 使用的redis连接,连接配置可在config/database.php中增加

这是Horizon将存储的Redis连接的名称,它运作所需的元信息。 它包括清单主管,失业,工作指标和其他信息。

/*
    |--------------------------------------------------------------------------
    | Horizon Redis Prefix
    |--------------------------------------------------------------------------
    |
    | This prefix will be used when storing all Horizon data in Redis. You
    | may modify the prefix when you are running multiple installations
    | of Horizon on the same server so that they don't have problems.
    |
    */

    'prefix' => env('HORIZON_PREFIX', 'horizon:'),

horizon 在redis中使用的存储前缀, 使用同一名称时,可以负载均衡水平扩展,不会重复处理队列中的任务.

在Redis中存储所有Horizon数据时将使用此前缀。 您可以在同一台服务器运行多个安装horizon时修改前缀,以便它们没有问题。

/*
    |--------------------------------------------------------------------------
    | Horizon Route Middleware
    |--------------------------------------------------------------------------
    |
    | These middleware will get attached onto each Horizon route, giving you
    | the chance to add your own middleware to this list or change any of
    | the existing middleware. Or, you can simply stick with this list.
    |
    */

    'middleware' => ['web'],

Horizon设置的路由中间件

这些中间件将附加到每个Horizon路由上,为您提供机会将您自己的中间件添加到此列表或更改任何现有的中间件

/*
    |--------------------------------------------------------------------------
    | Queue Wait Time Thresholds
    |--------------------------------------------------------------------------
    |
    | This option allows you to configure when the LongWaitDetected event
    | will be fired. Every connection / queue combination may have its
    | own, unique threshold (in seconds) before this event is fired.
    |
    */

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

队列等待时间阈值

此选项允许您配置LongWaitDetected事件将被解雇的时间。 每个连接/队列组合都可以拥有它,触发此事件之前的唯一阈值(以秒为单位)。

/*
    |--------------------------------------------------------------------------
    | Job Trimming Times
    |--------------------------------------------------------------------------
    |
    | Here you can configure for how long (in minutes) you desire Horizon to
    | persist the recent and failed jobs. Typically, recent jobs are kept
    | for one hour while all failed jobs are stored for an entire week.
    |
    */

    'trim' => [
        'recent' => 60,
        'failed' => 10080,
    ],

队列清空时间

在这里,您可以配置Horizon需要多长时间(以分钟为单位)坚持最近和失败的工作。 通常,保留最近的工作 一个小时,所有失败的工作都存储了整整一个星期。

/*
    |--------------------------------------------------------------------------
    | Fast Termination
    |--------------------------------------------------------------------------
    |
    | When this option is enabled, Horizon's "terminate" command will not
    | wait on all of the workers to terminate unless the --wait option
    | is provided. Fast termination can shorten deployment delay by
    | allowing a new instance of Horizon to start while the last
    | instance will continue to terminate each of its workers.
    |
    */

    'fast_termination' => false,

快速终止

当这个选项被启用.Horizon的 terminate 命令 将不会等待,直到所有的worker(进程)终止后才终止, 除非提供了–wait选项 .快速终止可以缩短部署延时时间,允许新的 Horizon实例在最后一个实例启动时,终止他的所有worker(进程)

/*
    |--------------------------------------------------------------------------
    | Queue Worker Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may define the queue worker settings used by your application
    | in all environments. These supervisors and settings handle all your
    | queued jobs and will be provisioned by Horizon during deployment.
    |
    */

    'environments' => [
        'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 3,
            ],
        ],

        'local' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 3,
                'tries' => 3,
            ],
        ],
    ],

队列worker(进程)配置

这里可以定义你应用程序在所有的环境中,使用的队列 worker(进程)的设置. 这些 supervisor 和 配置 处理你所有的队列任务 ,在部署期间将由Horizon提供

Redis超时问题

https://blog.minhow.com/2018/01/14/laravel/predis-error-reading/

1.修改 Laravel 的 config/database.php 配置文件,找到 redis 的配置项,加上 read_write_timeout 参数:
'redis' => [
        'cluster' => false,
        'default' => [
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
            'read_write_timeout' => 0//增加此设置
        ],
],
2.修改 Redis 的 redis.conf 配置文件,找到 timeout 参数,改成0
 timeout=0

Horizon 使用 Redis Cluster (集群)

https://github.com/laravel/horizon/issues/274

config/database.php

 'redis' => [

        'client' => env('REDIS_CLIENT', 'predis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'predis'),
            'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_',
        ],

        'clusters' => [
            'default' => [
                [
                    'host' => env('REDIS_HOST', 'localhost'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => 0,
                    'read_write_timeout' => 0
                ],
            ],
            'cache' => [
                [
                    'host' => env('REDIS_HOST', '127.0.0.1'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => env('REDIS_CACHE_DB', 1),
                    'read_write_timeout' => 0
                ]
            ],
            'horizon' => [
                [
                    'host' => env('REDIS_HOST', 'localhost'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => 2,
                    'read_write_timeout' => 0
                ],
            ],
        ],

config/horizon.php

 'use' => env('HORIZON_USE', 'clusters.default'),

最关键的配置

Redis 集群

如果你的 Redis 队列驱动使用了 Redis 集群,你的队列名必须包含一个 key hash tag 。这是为了确保所有的 Redis 键对于一个队列都被放在同一哈希中。

key hash tag 介绍 https://learnku.com/articles/25070

config/horizon.php 需要给队列名称加{},laravel是以队列名作为redis的key

'environments' => [
        'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['{default}'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 3,
            ],
        ],

        'local' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['{default}'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 3,
            ],
        ],
    ],

如果使用queue队列,则修改config/queue.php,给队列名称加{}

'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => '{default}',
    'retry_after' => 90,
],

Horizon不适用与redis集群

https://github.com/laravel/horizon/issues/274

horizon自定义队列配置

参考 https://github.com/laravel/horizon/issues/255

需求是要将队列的redis和和缓存的redis区分开,使用不同的redis。

目前尝试,默认队列一定要有,否则Job使用默认队列分发时,队列会出现不执行的情况。所以解决方案是修改config/queue.php中redis的链接来实现。

config/queue.php文件
 
'redis' => [
            'driver' => 'redis',
            'connection' => 'horizon',//修改队列连接
            'queue' => env('REDIS_QUEUE', 'default'),
            'retry_after' => 90,
            'block_for' => null,
 ],
  
//此处也可以增加自动定义队列
'horizon' => [
            'driver' => 'redis',
            'connection' => 'horizon',
            'queue' => env('HORIZON_REDIS_QUEUE', 'horizon'),
            'retry_after' => 1800,
            'block_for' => null,
],
config/horizon.php文件
默认队列要保留
'environments' => [
        'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 3,
            ],
    //此处对应horizon队列
            'horizon' => [
                'connection' => 'horizon',
                'queue' => ['horizon'],
                'balance' => 'simple',
                'processes' => 10,
                'tries' => 3,
                'timeout' => 0,
            ],
        ],

        'local' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 3,
                'tries' => 3,
            ],
 //此处对应horizon队列
            'horizon' => [
                'connection' => 'horizon',
                'queue' => ['horizon'],
                'balance' => 'simple',
                'processes' => 3,
                'tries' => 3,
                'timeout' => 0,
            ],
        ],
    ],