首页
/ Coolify 中 Laravel Horizon 的队列任务标签(Tags)与静默(Silencing)配置详解

Coolify 中 Laravel Horizon 的队列任务标签(Tags)与静默(Silencing)配置详解

2026-09-05 15:46:40作者:翟江哲Frasier

本文基于 Coolify 仓库中的技能参考文档 tags.md,讲解 Laravel Horizon 的任务标签(tagging)与静默(silencing)机制:Eloquent 模型任务的自动打标原理、自定义 tags() 方法的适用场景、silencedsilenced_tags 两个配置项的确切语义与边界,并结合 Coolify 源码展示部署任务如何通过标签被追踪。读完后可掌握在 Horizon 仪表盘中按标签筛选任务、以及如何用静默配置降低仪表盘噪音而不影响任务实际执行。

标签机制总览:Horizon 的任务身份标识

Horizon 的 Completed(已完成任务)仪表盘支持按标签过滤。标签是任务的“身份维度”,其来源有两类:

  1. 自动标签(auto-tagging):无需任何额外代码即可生效;
  2. 自定义标签:通过在 Job 类上定义 tags() 方法手动声明,用于补充自动标签无法覆盖的场景。

参考文档给出的判断准则很明确:只有当需要在自动标签之外附加自定义标签时,才需要编写 tags() 方法。这一准则在 Coolify 源码中有一个直接的反例式印证(见下文)。

Eloquent 模型任务会被自动打上 ModelClass:id 标签

根据 tags.md 的说明:

If a job's constructor accepts Eloquent model instances, Horizon automatically tags the job with ModelClass:id such as App\Models\User:42.

即:当 Job 构造函数接收 Eloquent 模型实例时,Horizon 会自动为该任务打上 ModelClass:id 格式的标签(例如 App\Models\User:42)。这类标签无需修改 Job 类即可在仪表盘中被过滤检索,也不会与自定义标签冲突。

Coolify 的实际做法:构造函数不接模型,因此显式编写 tags()

Coolify 的核心部署任务 ApplicationDeploymentJob 的构造函数接收的是一个整型队列 ID,而非 Eloquent 模型:

public function tags()
{
    // Do not remove this one, it needs to properly identify which worker is running the job
    return ['App\Models\ApplicationDeploymentQueue:'.$this->application_deployment_queue_id];
}

public function __construct(public int $application_deployment_queue_id)
{
    $this->onQueue(deployment_queue());
    // ...
}

这里手动构造了一个 App\Models\ApplicationDeploymentQueue:{id} 格式的标签,刻意模拟了自动标签的命名约定。源码注释特别强调“不要删除这个标签,它用于正确识别哪个 worker 正在执行该任务”——说明该标签不是装饰,而是运行期追踪链路的组成部分。

标签如何被消费:JobReserved 事件监听

标签的真实价值在 HorizonServiceProvider 中体现。Coolify 在 boot() 中监听了 Horizon 的 JobReserved 事件:

Event::listen(function (JobReserved $event) {
    $payload = $event->payload->decoded;
    $jobName = $payload['displayName'];
    if ($jobName === 'App\Jobs\ApplicationDeploymentJob') {
        $tags = $payload['tags'];
        $id = $payload['id'];
        $deploymentQueueId = collect($tags)->first(function ($tag) {
            return str_contains($tag, 'App\Models\ApplicationDeploymentQueue');
        });
        if (blank($deploymentQueueId)) {
            return;
        }
        $deploymentQueueId = explode(':', $deploymentQueueId)[1];
        $deploymentQueue = ApplicationDeploymentQueue::find($deploymentQueueId);
        $deploymentQueue->update([
            'horizon_job_id' => $id,
        ]);
    }
});

调用链可以概括为:任务被 worker 领取 → Horizon 发出 JobReserved 事件(payload 中携带 tags 与 Horizon job id)→ 监听器从标签中解析出部署队列 ID → 将该 Horizon job id 回写到 ApplicationDeploymentQueue 行的 horizon_job_id 字段。正是这条链路让 Coolify 的 UI 能够把“某次部署”与 Horizon 中“正在运行的 worker 进程”对应起来。这也印证了参考文档的判断准则:因为该任务构造函数不接收模型、无法依赖自动标签,所以必须显式实现 tags()

从源码结构看,HorizonServiceProvider 还注册了一个自定义的 CustomJobRepositoryapp/Repositories/CustomJobRepository.php),它在 RedisJobRepository 基础上扩展了按状态查询任务的能力,说明 Coolify 对 Horizon 的任务仓储层也有定制,但标签与静默机制本身仍完全遵循 Horizon 的标准行为。

silenced:从仪表盘隐藏指定 Job 类,但不阻止其执行

配置位置与当前取值

Coolify 的 config/horizon.php 中保留了 silenced 配置块:

/*
|--------------------------------------------------------------------------
| Silenced Jobs
|--------------------------------------------------------------------------
|
| Silencing a job will instruct Horizon to not place the job in the list
| of completed jobs within the Horizon dashboard. This setting may be
| used to fully remove any noisy jobs from the completed jobs list.
|
*/

'silenced' => [
    // App\Jobs\ExampleJob::class,
],

语义边界:这是降噪工具,不是禁用开关

参考文档对 silenced 的说明给出了一个极易被误读的关键点:

Adding a job class to the silenced array in config/horizon.php removes it from the completed jobs view. The job still runs normally. This is a dashboard noise-reduction tool, not a way to disable jobs.

即:将 Job 类加入 silenced 数组,只会让该任务不再出现在仪表盘的已完成任务列表中;任务本身照常入队、照常执行、照常失败重试。它不能替代“禁用 Job”的手段——如果目标是停止某类任务,应从未触发侧(移除 dispatch 调用、调整路由/调度)入手,而不是依赖 silenced

典型适用场景是那些高频、低信息量的任务(例如周期性心跳、状态轮询类 Job),它们会迅速把 Completed 视图刷满,静默后排查其他任务时信噪比更高。Coolify 当前仓库中该数组为空(示例类被注释),即未启用任何类级静默,可按需追加类名。

silenced_tags:按标签类别静默一整类任务

参考文档 tags.mdsilenced_tags 的说明:

Any job carrying a matching tag string is hidden from the completed jobs view. This is useful for silencing a category of jobs such as all jobs tagged notifications, rather than silencing specific classes.

silenced 按“Job 类”粒度隐藏不同,silenced_tags 按“标签字符串”粒度隐藏:任何携带匹配标签的任务都会被移出已完成视图。它的价值在于可以静默一个“类别”而非逐个枚举类。例如所有通知类任务若都带有 notifications 标签,只需在 config/horizon.php 中声明该标签即可整体隐藏,而不必为每个通知 Job 类单独加一条 silenced 记录。

两个配置的选型关系可以这样理解:

配置项 隐藏粒度 适用场景 是否影响执行
silenced Job 类 明确知道要隐藏哪几个类 否,任务照常运行
silenced_tags 标签字符串 按类别(如 notifications)批量隐藏 否,任务照常运行

需要注意的是:标签本身有自动与自定义两种来源(前文已述),silenced_tags 命中自动标签同样有效——例如按 App\Models\User: 前缀匹配的标签静默全部与 User 模型相关的任务,理论上可行,但实际使用时应优先选择稳定的自定义标签,避免误伤依赖自动标签的追踪逻辑(如 Coolify 的 ApplicationDeploymentQueue 标签就承担着 worker 识别职责,不应静默)。

落地建议与验证方式

结合参考文档 SKILL.md 的验证步骤,标签与静默配置可按以下流程落地:

  1. 先确认标签是否符合预期:运行 php artisan horizon 访问 /horizon,在 Completed 视图中查看目标任务的标签列;对构造函数携带 Eloquent 模型的任务,应能看到 ModelClass:id 形式的自动标签。
  2. 决定是否需要 tags():若任务构造函数不含模型、或自动标签不足以支撑筛选/追踪(如 Coolify 的 ApplicationDeploymentJob),再显式实现 tags() 方法,返回字符串数组。
  3. 配置静默:按类隐藏写入 config/horizon.phpsilenced;按类别隐藏写入 silenced_tags。配置后刷新仪表盘,确认目标任务已从 Completed 列表消失,同时通过日志或数据库确认其仍在正常执行。
  4. 注意静默的边界silenced/silenced_tags 只作用于仪表盘的已完成视图,Pending、Reserved、Failed 等其他状态视图与任务执行本身不受影响。

关键路径索引

以上内容均基于当前仓库实际文件;其中自动标签与 silenced_tags 的行为语义以参考文档 tags.md 的表述为准,适用前提为项目使用 Redis 队列驱动并运行 Laravel Horizon(Coolify 即通过 php artisan horizon 运行队列主进程)。

登录后查看全文
热门项目推荐
相关项目推荐