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