Coolify 中 Laravel Horizon 的队列任务标签(Tags)与静默(Silencing)配置详解
本文基于 Coolify 仓库中的技能参考文档 tags.md,讲解 Laravel Horizon 的任务标签(tagging)与静默(silencing)机制:Eloquent 模型任务的自动打标原理、自定义 tags() 方法的适用场景、silenced 与 silenced_tags 两个配置项的确切语义与边界,并结合 Coolify 源码展示部署任务如何通过标签被追踪。读完后可掌握在 Horizon 仪表盘中按标签筛选任务、以及如何用静默配置降低仪表盘噪音而不影响任务实际执行。
标签机制总览:Horizon 的任务身份标识
Horizon 的 Completed(已完成任务)仪表盘支持按标签过滤。标签是任务的“身份维度”,其来源有两类:
- 自动标签(auto-tagging):无需任何额外代码即可生效;
- 自定义标签:通过在 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:idsuch asApp\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 还注册了一个自定义的 CustomJobRepository(app/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
silencedarray inconfig/horizon.phpremoves 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.md 对 silenced_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 的验证步骤,标签与静默配置可按以下流程落地:
- 先确认标签是否符合预期:运行
php artisan horizon访问/horizon,在 Completed 视图中查看目标任务的标签列;对构造函数携带 Eloquent 模型的任务,应能看到ModelClass:id形式的自动标签。 - 决定是否需要
tags():若任务构造函数不含模型、或自动标签不足以支撑筛选/追踪(如 Coolify 的ApplicationDeploymentJob),再显式实现tags()方法,返回字符串数组。 - 配置静默:按类隐藏写入
config/horizon.php的silenced;按类别隐藏写入silenced_tags。配置后刷新仪表盘,确认目标任务已从 Completed 列表消失,同时通过日志或数据库确认其仍在正常执行。 - 注意静默的边界:
silenced/silenced_tags只作用于仪表盘的已完成视图,Pending、Reserved、Failed 等其他状态视图与任务执行本身不受影响。
关键路径索引
- 参考文档:.agents/skills/configuring-horizon/references/tags.md
- Horizon 配置文件(含
silenced配置块、supervisor 与 metrics 配置):config/horizon.php - 自定义标签示例:app/Jobs/ApplicationDeploymentJob.php
- 标签消费链路(
JobReserved监听与horizon_job_id回写):app/Providers/HorizonServiceProvider.php - 自定义任务仓储扩展:app/Repositories/CustomJobRepository.php
以上内容均基于当前仓库实际文件;其中自动标签与 silenced_tags 的行为语义以参考文档 tags.md 的表述为准,适用前提为项目使用 Redis 队列驱动并运行 Laravel Horizon(Coolify 即通过 php artisan horizon 运行队列主进程)。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00