Laravel 使用 Redis 作為 Queue Driver 並結合 Laravel Horizon 來監控與管理佇列工作

在 Laravel 中,使用 Redis 作為 Queue Driver 並結合 Laravel Horizon 來監控與管理佇列工作(queue jobs)是非常常見也高效的做法。以下是完整的建置與使用流程:

前置需求

  1. Laravel 專案(建議 Laravel 10+)
  2. Redis 伺服器(本地或遠端)
  3. Composer 套件:laravel/horizon

一、安裝 Laravel Horizon

composer require laravel/horizon

Laravel Horizon 依賴下面這兩個擴展來處理進程控制和管理,這對於它的佇列監控功能至關重要。

  • ext-posix (可移植操作系統接口)
  • ext-pcntl (進程控制)

針對 Windows 用戶

ext-pcntlext-posix 擴展通常不支援 Windows 作業系統,因為 Windows 在進程管理方面與類 Unix/Linux 系統(如 Linux、macOS)有根本性的差異。Laravel Horizon 主要設計用於類 Unix/Linux 環境,這些擴展在這些環境Unix/Linux中是標準配置。

解決方式

composer require laravel/horizon --ignore-platform-req=ext-pcntl --ignore-platform-req=ext-posix

在 windows 執行畫面如下

image 13

注意: 在windows環境中,雖然可以利用此方式安裝,但在執行時因為找不到 ext-pcntl & ext-posix ,依舊無法啟動

二、發佈資源與設定檔

php artisan horizon:install

這會產生:

  • config/horizon.php 設定檔
  • Service Provider: app\Providers\HorizonServiceProvider 服務檔

HorizonServiceProvider 如下:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Laravel\Horizon\Horizon;
use Laravel\Horizon\HorizonApplicationServiceProvider;

class HorizonServiceProvider extends HorizonApplicationServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        parent::boot();

        // Horizon::routeSmsNotificationsTo('15556667777');
        // Horizon::routeMailNotificationsTo('[email protected]');
        // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
    }

    /**
     * Register the Horizon gate.
     *
     * This gate determines who can access Horizon in non-local environments.
     */
    protected function gate(): void
    {
        Gate::define('viewHorizon', function ($user = null) {
            return in_array(optional($user)->email, [
                //
            ]);
        });
    }
}

並在 bootstrap/providers 中加入此服務

<?php

return [
    App\Providers\AppServiceProvider::class,
    App\Providers\HorizonServiceProvider::class,
];

三、設定 .env 使用 Redis Queue

在環境檔 .env 內容修改如下

QUEUE_CONNECTION=redis

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

四、執行 Horizon 並觀察 UI

啟動與中止

php artisan horizon:status     # 檢查 Horizon 狀態
php artisan horizon:pause      # 暫停處理
php artisan horizon:continue   # 繼續處理
php artisan horizon:terminate  # 停止 Horizon

Laravel Horizon 提供一個漂亮的網頁儀表板,預設網址為:

http://your-app.test/horizon

五、限制 Horizon Dashboard 存取(中介層)

可透過 routes/web.php 控制存取權限,例如只限登入使用者或特定角色。或是編輯 app/Providers/HorizonServiceProvider.php

use Laravel\Horizon\Horizon;

public function boot()
{
    Horizon::auth(function ($request) {
        return auth()->check() && auth()->user()->isAdmin(); // 自訂邏輯
    });
}

或是在 gate 中設定

/**
 * Register the Horizon gate.
 *
 * This gate determines who can access Horizon in non-local environments.
 */
protected function gate(): void
{
    Gate::define('viewHorizon', function (User $user) {
        return in_array($user->email, [
            '[email protected]',
        ]);
    });
}

六、排程與監控 Horizon

建議在 production 環境使用 supervisor 或 systemd 管理 horizon 程序,確保它不會意外中斷。

Supervisor 設定範例:

Installing Supervisor

sudo apt-get install supervisor

Supervisor Configuration

建立 /etc/supervisor/conf.d/horizon.conf:(或是 /etc/supervisor/conf.d)

[program:horizon]
process_name=%(program_name)s
command=php /path-to-your-project/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/path-to-your-project/storage/logs/horizon.log

Starting Supervisor

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start horizon

七、重要概念

  • Queues:可以在 config/horizon.php 自訂不同 queue 的處理邏輯與 worker 數。
  • Tags:你可在 job 類別中自訂 tags() 方法以利追蹤。
  • Metrics:Horizon 可顯示平均處理時間、失敗率、吞吐量等。
  • Failed Jobs:整合 Laravel 的 failed_jobs 表,可從 UI 重新執行。

重要提示:針對 Windows 用戶

ext-pcntlext-posix 擴展通常不支援 Windows 作業系統,因為 Windows 在進程管理方面與類 Unix 系統(如 Linux、macOS)有根本性的差異。Laravel Horizon 主要設計用於類 Unix 環境,這些擴展在這些環境中是標準配置。

如果您正在使用 Windows,有幾種解決方案:

  • 使用 WSL (Windows Subsystem for Linux):這是最推薦的方法。在 Windows 上安裝一個 Linux 發行版(例如 Ubuntu),然後在 WSL 環境中建立您的 Laravel 開發環境。這將提供一個真正的 Linux 環境,其中 pcntlposix 擴展是可用的。
  • 使用虛擬機 (例如 Vagrant、VirtualBox):在您的 Windows 機器上設定一個基於 Linux 的虛擬機,並在其中進行開發。
  • 部署到 Linux 伺服器:如果這是用於生產環境,最終也需要將您的應用程式部署到 Linux 伺服器上。

重新執行 Composer 安裝

在啟用這些擴展(或轉移到 Linux 環境)之後,請再次嘗試安裝 Horizon:

composer require laravel/horizon

現在 Composer 應該能夠找到與 PHP 8.3.20 和新啟用的擴展相容的 Laravel Horizon 版本。最新的版本 (v5.33.1) 應該能正常工作。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


內容索引