Yet-another swoole 非同步佇列,支援彈性擴容,工作程式協程支援

Littlesqx發表於2020-03-12

專案 在這裡,歡迎 star 鴨!寫這個庫的原因主要是當時在學 Swoole,然後發現 Swoole 社群中沒有一個寫得比較好又是專門針對非同步任務的庫,所以就一邊學一邊寫了。去年年中開始寫的,參考了各個類似專案,並且在實際業務應用中發現了問題,一路上改進了不少,目前在公司已經有應用在郵件投遞服務(實際上還在測試階段中:joy:)。大家有什麼意見或建議可以提出來,我會好好改進。

基於 Swoole 的一個非同步佇列庫,可彈性伸縮的工作程式池,工作程式協程支援。

特性

  • 預設 Redis 驅動
  • 秒級延時任務
  • 自定義重試次數和時間
  • 自定義錯誤回撥
  • 支援任務執行中介軟體
  • 自定義佇列快照事件
  • 彈性多程式消費
  • 工作程式協程支援

環境

  • PHP 7.2+
  • Swoole 4.4+
  • Redis 3.2+ (redis 驅動)

安裝

$ composer require littlesqx/aint-queue -vvv

使用

配置

預設讀取配置路徑: config/aint-queue.php, 不存在時讀取 /vendor/littlesqx/aint-queue/src/Config/config.php

<?php

use Littlesqx\AintQueue\Driver\Redis\Queue as RedisQueue;
use Littlesqx\AintQueue\Logger\DefaultLogger;

return [
    // channel_name => [...config]
    'default' => [
        'driver' => [
            'class' => RedisQueue::class,
            'connection' => [
                'host' => '127.0.0.1',
                'port' => 6379,
                'database' => '0',
                // 'password' => 'password',
            ],
            'pool_size' => 8,
            'pool_wait_timeout' => 1,
            'handle_timeout' => 60 * 30,
        ],
        'logger' => [
            'class' => DefaultLogger::class,
                'options' => [
                    'level' => \Monolog\Logger::DEBUG,
                ],
            ],
        'pid_path' => '/var/run/aint-queue',
        'consumer' => [
            'sleep_seconds' => 1,
            'memory_limit' => 96,
            'dynamic_mode' => true,
            'capacity' => 6,
            'flex_interval' => 5 * 60,
            'min_worker_number' => 5,
            'max_worker_number' => 30,
            'max_handle_number' => 0,
        ],
        'job_snapshot' => [
            'interval' => 5 * 60,
            'handler' => [],
        ],
    ],
];

所有引數:

name type comment default
channel string 頻道。佇列的單位,每個頻道內的訊息對應著各自的消費者和生產者。支援多頻道。在命令列使用 --channel 引數。 default
driver.class string 佇列驅動類,需要實現 QueueInterface。 Redis
driver.connection map 驅動配置。
pid_path string 主程式的 PID 檔案儲存路徑。注意執行使用者需要可讀寫許可權。 /var/run/aint-queue
consumer.sleep_seconds int 當任務空閒時,每次 pop 操作後的睡眠秒數。 1
consumer.memory_limit int 工作程式的最大使用記憶體,超出則重啟。單位 MB。 96
consumer.dynamic_mode bool 是否開啟自動伸縮工作程式。 true
consumer.capacity int 代表每個工作程式在短時間內並且健康狀態下的最多處理訊息數,它影響了工作程式的自動伸縮策略。 5
consumer.flex_interval int flex_interval 秒,監控程式嘗試調整工作程式數(假設開啟了自動伸縮工作程式)。 5
consumer.min_worker_number int 工作程式最小數目。 5
consumer.max_worker_number int 工作程式最大數目。 30
consumer.max_handle_number int 當前工作程式最大處理訊息數,超出後重啟。0 代表無限制。 0
job_snapshot map 每隔 job_snapshot.interval 秒,job_snapshot.handles 會被依次執行。job_snapshot.handles 需要實現 JobSnapshotterInterface。

訊息推送

可以在 cli/fpm 執行模式下使用:

<?php

use Littlesqx\AintQueue\Driver\DriverFactory;

$queue = DriverFactory::make($channel, $options);

// push a job
$queue->push(function () {
    echo "Hello aint-queue\n";
});

// push a delay job
$closureJob = function () {
    echo "Hello aint-queue delayed\n";
};
$queue->push($closureJob, 5);

更建議使用類任務,這樣功能上會更加完整,也可以獲得更好的編碼體驗和效能。

  • 建立的任務類需要繼承 JobInterface,詳細可參考 /example

    • handle(): void: 任務主體,你要執行的內容,在這裡可以使用 swoole 的相關 api(比如建立協程等);

    • canRetry(int $attempt, $error): bool: 決定是否要重試;

    • retryAfter(int $attempt): int: 決定重試延時時間;

    • failed(int $id, array $payload): void: 任務徹底失敗了(就是達到了重試次數還沒成功);

    • middleware(): array: 當前任務的中介軟體列表,原理參考 laravel pipeline 流水線

  • 注意任務必須能在生產者和消費者中(反)序列化,意味著需要在同一個專案

  • 利用佇列快照事件你可以實現佇列實時監控,而利用任務中介軟體,你可以實現任務執行速率限制,任務執行日誌等。

佇列管理

推薦使用 Supervisor 等程式管理工具守護工作程式。

vendor/bin/aint-queue
AintQueue Console Tool

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help                 Displays help for a command
  list                 Lists commands
 queue
  queue:clear          Clear the queue.
  queue:reload-failed  Reload all the failed jobs onto the waiting queue.
  queue:status         Get the execute status of specific queue.
 worker
  worker:listen        Listen the queue.
  worker:reload        Reload worker for the queue.
  worker:run           Run the specific job.
  worker:stop          Stop listening the queue.

測試

composer test

貢獻

可以通過以下方式貢獻:

1. 通過 issue tracker 提交 bug 或者建議給我們。
2. 回答 issue tracker 中的問題或者修復 bug。
3. 更新和完善文件,或者提交一些改進的程式碼給我們。

貢獻沒有什麼特別的要求,只需要保證編碼風格遵循 PSR2/PSR12,排版遵循 中文文案排版指北

License

MIT

本作品採用《CC 協議》,轉載必須註明作者和本文連結

癩蛤蟆想吃燉大鵝

相關文章