定制 smwks/laravel-zenith 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

smwks/laravel-zenith

Composer 安装命令:

composer require smwks/laravel-zenith

包简介

Laravel Horizon for database-backed queues — real-time dashboard and worker management for the database queue driver.

README 文档

README

Zenith for Laravel

Zenith For Laravel

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Think Laravel Horizon, but for database-backed queues. Zenith brings the same real-time visibility and worker management that Horizon provides for Redis — to the database queue driver.

If you're running queues out of your database and want a live dashboard, worker process management, and job lifecycle tracking without switching to Redis, Zenith is built for you. See pending, processing, completed, and failed jobs alongside the worker processes handling them. Scale workers up or down, terminate supervisors, retry failures in bulk, and track performance over time — all from your browser, all without leaving your application.

Quick Install

composer require smwks/laravel-zenith
php artisan vendor:publish --tag="zenith-migrations"
php artisan migrate

Then visit /zenith in your browser. The dashboard is protected by the auth middleware by default.

Start workers with:

php artisan zenith:work --queue=default

Add the monitor to your scheduler in routes/console.php:

Schedule::command('zenith:monitor')->everyMinute();

Run A Demo

Spin up a fresh Laravel app with Zenith installed in under a minute:

# new Laravel app without auth scaffolding since Zenith doesn't require it
laravel new -n demo-laravel-zenith
cd demo-laravel-zenith

# install Zenith
composer require smwks/laravel-zenith

php artisan vendor:publish --tag="zenith-config"

# **NOTE:** now go to update config/zenith.php to disable auth middleware
# 'route' => [
#     'middleware' => ['web'], // remove 'auth' since this is a demo
# ],

# publish and run migrations
php artisan vendor:publish --tag="zenith-migrations"
php artisan migrate

# start the demo worker (which dispatches test jobs every 10 seconds)
php artisan zenith:work

# in a separate terminal, start the server
php artisan serve

Notes:

  • -n in laravel new skips the default auth scaffolding since Zenith doesn't require it.
  • With the above steps also update zenith.php config to remove auth from the middleware array.

Then browse to http://localhost:8000/zenith to see the dashboard.

Features

Live Dashboard

A real-time overview of your queue system refreshing every 5 seconds. At a glance: how many workers are active, how many are idle or stuck, jobs pending and completed today, average processing time, throughput (jobs/hour), and failure rate.

Job Visibility Across the Full Lifecycle

Browse every stage of a job's journey across dedicated tabs:

  • Pending — jobs waiting in the queue, filterable by queue name
  • Completed — successful jobs with processing time and batch membership
  • Failed — full exception messages, per-job retry and delete, bulk retry all
  • Batches — batch progress bars, pending/failed counts, status at a glance

Jobs list

Worker Management

The Workers page shows the full supervisor/child process hierarchy. For each supervisor you see its queue, connection, worker count, total jobs processed, last heartbeat, and uptime. For each child worker you see individual job counts, health status, and a "Stuck" indicator when a heartbeat goes missing.

From the UI you can:

  • Scale Up — spawn an additional child worker under a supervisor (manual balance only)
  • Scale Down — remove a child worker gracefully (manual balance only)
  • Terminate — send a shutdown signal to a supervisor

Supervisor Groups & Balance Strategies

Each zenith:work invocation is tied to a named supervisor group defined in config/zenith.php. Groups configure the queue, connection, and — importantly — the balance strategy:

Strategy Behaviour
fixed Workers start at min_workers and stay there. Scale Up/Down hidden in the UI. Ideal for Kubernetes pods or any environment where the process supervisor controls scale.
manual Workers start at min_workers. Scale Up/Down buttons are visible in the dashboard. Operator-driven scaling within min_workers/max_workers bounds.
automatic Workers start at min_workers and scale to demand on every heartbeat tick. Scale target is ceil(pending_jobs / jobs_per_worker), clamped to min_workers/max_workers. Scales up to target immediately; scales down one step per tick only when the queue is empty.

Workers list

Heartbeat-Based Health Monitoring

Every worker reports a heartbeat on a configurable interval (default: 30 seconds). The zenith:monitor command — run every minute via the scheduler — compares last heartbeat times against a configurable stuck threshold (default: 120 seconds). Workers that go silent are marked terminated; jobs held by those workers can be automatically released back to the queue.

Job Lifecycle Events

Zenith hooks into Laravel's job events to record a JobEvent at every transition: started, completed, failed, retried, cancelled. Each event captures the queue, connection, attempt count, and processing time. The event log is the foundation for metrics, audit trails, and debugging.

API

All dashboard data is also available via JSON endpoints under /zenith/api/ — useful for external monitoring systems or custom tooling.

Endpoint Description
GET /zenith/api/metrics Full metrics snapshot
GET /zenith/api/metrics/workers Worker counts
GET /zenith/api/metrics/jobs Job counts
GET /zenith/api/metrics/performance Throughput and timing
GET /zenith/api/metrics/queues Per-queue pending counts
GET /zenith/api/workers Worker list
GET /zenith/api/workers/{id} Worker detail
GET /zenith/api/jobs Pending jobs
GET /zenith/api/jobs-history Completed/cancelled jobs
GET /zenith/api/jobs-failed Failed jobs
DELETE /zenith/api/jobs/{id} Cancel a pending job
POST /zenith/api/jobs/{id}/retry Retry a failed job
POST /zenith/api/jobs/retry-all Retry all failed jobs

Built-In Test Dispatcher

The Tests tab dispatches real jobs through your queue so you can verify the full stack is wired up correctly. Dispatch a single job or a batch of configurable size, with optional logging enabled, and watch them flow through the dashboard in real time.

Installation

1. Install via Composer

composer require smwks/laravel-zenith

2. Publish and Run Migrations

php artisan vendor:publish --tag="zenith-migrations"
php artisan migrate

This creates three tables: zenith_processes, zenith_history, and zenith_events.

3. Publish the Config (optional)

php artisan vendor:publish --tag="zenith-config"

4. Publish the Views (optional)

php artisan vendor:publish --tag="zenith-views"

Artisan Commands

zenith:work

The primary worker command. Replaces queue:work with full Zenith monitoring.

php artisan zenith:work --queue=default --name=my-worker
Option Default Description
--name default Supervisor group name — must match a key in config('zenith.supervisors') to pick up its balance strategy and worker bounds
--queue Comma-separated queue names (overrides the group's configured queue)
--memory 128 Memory limit in MB
--timeout 60 Max seconds a job may run
--sleep 3 Seconds to sleep when queue is empty
--tries 1 Max attempts before a job is failed
--backoff 0 Seconds to wait between retries
--max-jobs 0 Stop after processing this many jobs (0 = unlimited)
--max-time 0 Stop after this many seconds (0 = unlimited)
--stop-when-empty Stop when the queue is drained
--force Run even in maintenance mode

zenith:monitor

Detects stuck workers and optionally releases their held jobs back to the queue. Run this every minute via the scheduler.

php artisan zenith:monitor
php artisan zenith:monitor --auto-retry

zenith:prune

Removes old records to keep the database lean. Safe to schedule daily.

php artisan zenith:prune
php artisan zenith:prune --completed=7 --failed=30 --events=7
Option Default Description
--completed 7 Days to retain completed job history
--failed 30 Days to retain failed job records
--events 7 Days to retain job events
--all Prune all types at once using config defaults

Configuration

// config/zenith.php
return [

    // Master switch — disable to stop all monitoring without removing the package
    'enabled' => env('ZENITH_ENABLED', true),

    'route' => [
        'domain'     => env('ZENITH_ROUTE_DOMAIN', null),      // restrict dashboard to a specific domain
        'prefix'     => env('ZENITH_ROUTE_PREFIX', 'zenith'),
        'middleware' => ['web', 'auth'],
    ],

    // Named supervisor groups — each `zenith:work --name=X` invocation reads from its group
    'supervisors' => [
        'default' => [
            'connection'      => env('QUEUE_CONNECTION', 'database'),
            'queue'           => 'default',
            'balance'         => env('ZENITH_BALANCE', 'fixed'),      // fixed | manual | automatic
            'min_workers'     => env('ZENITH_MIN_WORKERS', 1),
            'max_workers'     => env('ZENITH_MAX_WORKERS', 1),
            'jobs_per_worker' => env('ZENITH_JOBS_PER_WORKER', 5),    // automatic balance only
        ],
    ],

    // How often workers report their heartbeat (seconds)
    'heartbeat_interval' => env('ZENITH_HEARTBEAT_INTERVAL', 30),

    // How long without a heartbeat before a worker is considered stuck (seconds)
    'stuck_job_threshold' => env('ZENITH_STUCK_JOB_THRESHOLD', 120),

    // Automatically release stuck jobs back to the queue
    'auto_retry_stuck_jobs' => env('ZENITH_AUTO_RETRY_STUCK_JOBS', false),

    'retention' => [
        'completed_jobs' => env('ZENITH_RETAIN_COMPLETED_JOBS', 7),
        'failed_jobs'    => env('ZENITH_RETAIN_FAILED_JOBS', 30),
        'job_events'     => env('ZENITH_RETAIN_JOB_EVENTS', 7),
    ],

    // Override the database connection used by Zenith tables
    'database_connection' => env('ZENITH_DB_CONNECTION', null),

];

Multiple named groups are supported — useful when different queues need different strategies:

'supervisors' => [
    'default' => [
        'queue'       => 'default',
        'balance'     => 'fixed',
        'min_workers' => 2,
        'max_workers' => 2,
    ],
    'high-priority' => [
        'queue'           => 'high,default',
        'balance'         => 'automatic',
        'min_workers'     => 1,
        'max_workers'     => 8,
        'jobs_per_worker' => 10,
    ],
],

Then start each group as a separate process:

php artisan zenith:work --name=default
php artisan zenith:work --name=high-priority

Recommended Scheduler Setup

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('zenith:monitor')->everyMinute();
Schedule::command('zenith:prune --all')->daily();

How It Works

Process Model

zenith:work starts a supervisor process that manages a pool of child worker processes. Each child runs queue:work under the hood. The supervisor monitors its children and respawns them if they exit, and listens for scaling instructions delivered via the heartbeat action column in the database.

Heartbeats

On every worker loop iteration, Zenith updates last_heartbeat_at in the zenith_processes table for both the worker and its supervisor. zenith:monitor compares these timestamps against stuck_job_threshold and marks unresponsive processes as terminated. If auto_retry_stuck_jobs is enabled, any job the stuck worker was holding gets released back to the queue automatically.

Job Events

Zenith registers listeners for Laravel's built-in job lifecycle events:

Laravel Event Zenith Action
JobProcessing Records a started event, marks worker as working
JobProcessed Records a completed event, writes JobHistory, marks worker idle, increments jobs_completed
JobFailed Records a failed event, captures exception, writes JobHistory, increments jobs_failed

Each JobHistory record stores the full payload, processing time in milliseconds, attempt count, queue, and connection. The JobEvent log provides the per-transition audit trail that drives the dashboard metrics.

Dashboard Metrics

The MetricsService computes all metrics on demand from the Zenith tables:

  • Active workers — processes with status idle or working
  • Completed todayJobHistory records with completed_at today
  • Jobs per hourcompleted events in the last 60 minutes
  • Failure rate(failed / (failed + completed)) * 100 over the same window
  • Avg processing time — mean of processing_time_ms from today's completed jobs

Testing

composer test

Changelog

Please see CHANGELOG for recent changes.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

smwks/laravel-zenith 适用场景与选型建议

smwks/laravel-zenith 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 87 次下载、GitHub Stars 达 18, 最近一次更新时间为 2026 年 02 月 24 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「laravel」 「smwks」 「laravel-zenith」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 smwks/laravel-zenith 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 smwks/laravel-zenith 我们能提供哪些服务?
定制开发 / 二次开发

基于 smwks/laravel-zenith 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 87
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 18
  • 点击次数: 23
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 18
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-02-24