tillmannschiffler / simplequeue
针对 PHP8.x 的异步任务实用方法
Requires
- php: ^8.0
- ext-pcntl: *
Requires (Dev)
- infection/infection: ^0.26.16
- laravel/pint: ^1.5
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.0
- vimeo/psalm: ^5.9
README
针对 PHP8.x 的异步任务实用方法
想法
这个PHP项目是为所有希望不安装大型依赖项即可获得队列系统的开发者设计的。该项目深受来自 thePHP.cc 的 Arne Blankerts 的讲座 Daemons with PHP 的启发
如果你在项目中遇到需要异步任务的情况,你通常会倾向于使用像 RabbitMQ 这样的大型解决方案或其他系统。在意识到这样的服务需要维护和更新后,你可能会寻找更简单的解决方案,如 Laravel 框架的队列包。快速 PHPloc 会给出类似以下内容
./tools/phploc vendor/illuminate/
Directories 96
Files 653
Size
Lines of Code (LOC) 108002
没错 ... 650+ 个文件,超过 100k 行代码。
这是一个例子,展示在使用 composer 安装 enqueue 包之后的 "enqueue" 包
Installing doctrine/cache
Installing doctrine/collections
Installing doctrine/event
Installing symfony/polyfill
Installing ramsey/collection
Installing brick/math
Installing ramsey/uuid
Installing queue-interop
Installing psr/cache
Installing doctrine/persistence
Installing doctrine/dbal
Installing enqueue/dbal
这些都是巨大的依赖项,需要维护。现在,这个包旨在尽可能小,但提供重要的功能
- 异步任务。
- 不会意外地多次执行同一个任务。
- 带有最大工作员数的并行任务
- 事件驱动
所有这些功能都可以通过使用最基础的存储,即文件系统,并利用 systemd 来实现。
systemd 使用单元文件来配置守护进程,路径单元监控文件和目录以查找事件。当发生指定事件时,会执行具有相同名称的服务单元。我将通过一个例子来演示这一点。所以,概念是在特定目录中创建文件,让 systemd 处理启动事件条件,并保持该单元运行,以避免意外地多次执行同一个任务。
要求
- 带有 systemd 的 Linux 操作系统
- 所需的最小 PHP 版本为 PHP 8.0
安装
全局安装
步骤 1/2
要使用此库,请使用以下命令进行安装
composer require tillmannschiffler/simplequeue
要开始使用此系统,您可以首先修改位于 /src/Example 的示例文件。您可以根据自己的需求修改这些文件。例如,您可以根据自己的需求自定义 Sample Processor。
步骤 2/2
设置 systemd 配置文件,如下例所示
文件:/etc/systemd/system/SimpleQueue.path
[Unit]
Description="Monitor for changes in Queue Inbox Path"
[Path]
DirectoryNotEmpty=<THE_DIR_TO_INBOX>
Unit=SimpleQueue.service
[Install]
WantedBy=multi-user.target
文件:/etc/systemd/system/SimpleQueue.service
[Unit]
Description="Worker Starter for the Queue/Job handling
[Service]
Type=simple
ExecStart=/usr/bin/php <PATH_TO_YOUR_WORKER.php>
[Install]
WantedBy=multi-user.target
请记住重新加载守护进程并启用这两个单元,以便在启动时启动它们
systemctl daemon-reload
systemctl enable SimpleQueue.path SimpleQueue.service
当然,启动它
systemctl start SimpleQueue.path SimpleQueue.service
针对开发人员的单个用户安装
在生产中,你可能会在全局 systemd 配置中安装队列服务。对于开发,你可以在用户的 systemd 配置中安装它,这也不需要 root 权限。以下详细说明了所需的步骤
-
创建
systemd
配置目录mkdir -p ~/.config/systemd/user
-
安装配置文件
安装以下文件,将
<GIT_ROOT>
替换为源代码检查出的绝对路径。文件:~/.config/systemd/user/SimpleQueue.path
[Unit] Description=Monitor for changes in Queue Inbox Path [Path] # NOTE: adjust path to the queue/inbox directory DirectoryNotEmpty=<GIT_ROOT>/queue/inbox Unit=SimpleQueue.service [Install] WantedBy=multi-user.target
文件:~/.config/systemd/user/SimpleQueue.service
[Unit] Description=Worker Starter for the Queue/Job handling [Service] Type=simple # NOTE: adjust path to the worker here ExecStart=/usr/bin/php <GIT_ROOT>/src/Example/SampleWorker.php [Install] WantedBy=multi-user.target
-
启动收件箱监控器
systemctl --user daemon-reload systemctl --user start SimpleQueue.path
现在,您可以使用
journalctl --user
进行检查,它应该包含一个消息,说明收件箱监控器已启动。
您可以通过查看 systemd
日志来监控队列的操作。只需在终端中运行 journalctl --follow --user --unit SimpleQueue.service
即可。为了测试队列,请使用 php src/Example/CreateSomeJobs.php 1
,这将创建一个单独的任务。在 systemd 日志中,您应该收到四个事件条目,分别是 StartedJob
、StartedExecution
、JobOutput
和 FinishedJob
。
运行中
要创建一个任务,您有两个选项:您可以手动创建任务并将其移动到 /queue/inbox 目录,或者您可以使用位于 /src/Example/CreateSomeJobs.php 的辅助文件。这个文件可以帮助您快速轻松地生成任务。
创建任务后,您可以运行 /src/Example/SingleWorker.php 来测试系统。这将帮助您确保设置按预期工作。如果有任何问题,您可以相应地调试系统。通过这个简单的设置过程,您可以立即开始使用此系统。
请随时通过邮件告诉我您的想法或发现的错误 tillmann.schiffler@gmail.com
监控
由于我们打算使用文件系统作为任务的后端存储。监控就像听起来那么简单。
获取任务的数量,只需计算相应目录中的文件数量,例如
ls | wc -l
在收件箱目录中,等等。
由于本项目利用 systemd 作为优势,我们可以使用日志记录获取按时间范围的统计信息。
journalctl -u SimpleQueue.path --since "1 minute ago" | grep "Started SimpleQueue.path" | wc -l
要获取任务吞吐量,还有一个简单实用的方法 - 使用 "emitFinishedJob" 事件的订阅者并将该事件写入 systemd 的日志。之后,您可以使用上面的命令确定在时间范围内完成的工作量。