duanvnc/php-resque

Redis支持的库,用于创建后台任务并在以后处理它们。基于Ruby resque。

v1.1 2019-10-30 06:54 UTC

This package is auto-updated.

Last update: 2024-09-29 05:09:07 UTC


README

PHP Resque 是一个Redis支持的库,用于创建后台任务,将任务放入队列,并在将来某个时间处理这些任务。

构建状态: 构建状态

背景

Resque 由GitHub的优秀团队开创并开发,用Ruby编写。您在这里看到的是将Resque工作进程和入队系统移植到PHP。

有关Resque的更多信息,请访问官方GitHub项目:https://github.com/resque/resque

此PHP移植版提供了与Ruby版本几乎相同的特性

  • 工作进程可以在多台机器之间分布
  • 支持优先级(队列)
  • 具有内存泄漏恢复能力(分叉)
  • 期望失败
  • 自定义失败后端
  • 能够出队任务
  • 生命周期事件

它还支持以下附加功能

  • 当分叉的子进程在运行任务时没有干净退出时,将任务标记为失败
  • 在适当的时候使用Redis事务
  • 避免单例

要求

  • PHP 5.4+
  • Redis 2.2+
  • Composer

入门指南

当php-resque作为项目内部的Composer包安装时,与php-resque一起工作是最容易的方式。

如果您不熟悉Composer,请参阅 https://composer.php.ac.cn/

将php-resque添加到应用程序的composer.json中。

composer require php-resque/resque:dev-master

任务

排队任务

任务按以下方式排队

$resque = new Resque\Component\Core\Resque(/* predis connection */);
$resque->enqueue('default', 'Acme\My\Job', array('name' => 'Chris'));

这里假设您对默认内部设置感到满意。

定义任务

每个任务都应该有自己的类,并实现 Resque\Component\Job\PerformantJobInterface 接口。

namespace Acme\My;

use Resque\Component\Job\PerformantJobInterface;

class Job implements PerformantJobInterface
{
    public function perform($args)
    {
        // Work work work
        echo $args['name'];
    }
}

任务抛出的任何异常都会导致任务失败 - 请小心处理,确保您处理了不应该导致任务失败的异常。

出队/删除任务

队列允许您以下方式从队列中删除任务

// Simply remove it by a job id
$queue->remove(array('id' => $job->getId()));
// remove jobs by matching the class
$queue->remove(array('class' => 'Acme/Job'));

如果没有提供删除过滤器,则不会删除任何任务。但是,您可以使用以下方式删除队列中的所有任务以及队列本身

$queue->deregister();

删除和注销都返回被删除的任务数量。

跟踪任务状态

php-resque具有执行队列中任务的基本状态跟踪功能。状态信息将允许您检查任务是否在队列中,是否正在运行,是否已完成或已失败。

要跟踪任务的状态,将 true 作为 Resque::enqueue 的第四个参数传递。将返回用于跟踪任务状态的令牌

$token = Resque::enqueue('default', 'My_Job', $args, true);
echo $token;

要获取任务的状态

$status = new Resque_Job_Status($token);
echo $status->get(); // Outputs the status

任务状态在 Resque_Job_Status 类中定义为常量。有效的状态包括

  • Resque_Job_Status::STATUS_WAITING - 任务仍在队列中
  • Resque_Job_Status::STATUS_RUNNING - 任务正在运行
  • Resque_Job_Status::STATUS_FAILED - 任务已失败
  • Resque_Job_Status::STATUS_COMPLETE - 任务已完成
  • false - 获取状态失败 - 令牌是否有效?

任务完成或失败后,状态可保留至多24小时,然后自动过期。也可以通过在状态类上调用 stop() 方法强制过期状态。

工作者

工作者与Ruby工作者几乎以相同的方式工作。有关工作者的完整文档,请参阅原始文档。

包含一个基本的“启动运行”的 bin/resque 文件,用于设置运行的工作者环境。 (vendor/bin/resque 通过Composer安装)

与Ruby版本resque的相似性中有一个例外,那就是工作者的初始设置。PHP端口不假设您的设置,除了依赖composer外,以适应所有环境。

启动工作者与Ruby版本非常相似

$ QUEUE=file_serve bin/resque

您需要负责告诉工作者要包含哪个文件以启动应用程序。您可以通过设置 APP_INCLUDE 环境变量来实现

$ QUEUE=file_serve APP_INCLUDE=../application/init.php bin/resque

启动应用程序还包括通过自动加载器或包含它们的方式告诉工作者您的作业类。

或者,您始终可以从应用程序中 include('bin/resque') 并完全跳过设置 APP_INCLUDE。只需确保在执行之前设置好各种环境变量 (setenv) 即可。

日志记录

端口支持相同的日志记录到STDOUT的环境变量。设置 VERBOSE 将打印基本调试信息,而 VVERBOSE 将打印详细信息。

$ VERBOSE=1 QUEUE=file_serve bin/resque
$ VVERBOSE=1 QUEUE=file_serve bin/resque

优先级和RedisQueue列表

类似地,优先级和队列列表功能与Ruby工作者完全相同。多个队列应以逗号分隔,并且它们提供的顺序是检查的顺序。

按照原始示例

$ QUEUE=file_serve,warm_cache bin/resque

在检查 warm_cache 队列之前,将始终在每个迭代中检查 file_serve 队列以获取新作业。

运行所有队列

所有队列都以相同的方式受支持并按字母顺序处理

$ QUEUE='*' bin/resque

运行多个工作者

可以通过提供 COUNT 环境变量同时启动多个工作者

$ QUEUES=emails COUNT=5 bin/resque

但是请注意,每个工作者都是其自己的分叉,原始进程将在生成 COUNT 个分叉后立即关闭。如果您需要使用如 monit 这样的外部应用程序跟踪工作者,您需要绕过这个限制。

自定义前缀

当您有多个应用程序使用相同的Redis数据库时,最好使用自定义前缀来分离Resque数据

$ PREFIX=my-app-name bin/resque

分叉

类似于Ruby版本,支持的平台将在获取作业后立即分叉。分叉的子进程将在作业完成后立即退出。

与php-resque的区别在于,如果分叉的子进程没有干净地退出(PHP错误等),php-resque将自动失败作业。

信号

信号在支持的平台上的工作方式与Ruby版本的Resque完全相同

  • QUIT - 等待作业完成处理然后退出
  • TERM / INT - 立即终止作业然后退出
  • USR1 - 立即终止作业但不要退出
  • USR2 - 暂停工作者,不会处理新作业
  • CONT - 恢复工作者。

进程标题/状态

Resque 的 Ruby 版本有一个巧妙的功能,即工作进程的进程标题会更新以指示工作进程正在执行的操作,并且任何分叉的子进程也会使用正在运行的作业来设置其进程标题。这有助于识别服务器上正在运行的过程及其 Resque 状态。

PHP 在 5.5 之前默认没有这个功能。

存在一个 PECL 模块(http://pecl.php.net/package/proctitle),它可以将此功能添加到 PHP 5.5 之前的版本中。因此,如果您想更新进程标题,请安装 PECL 模块。php-resque 将自动检测并使用它。

事件系统

php-resque 随附一个基本的事件系统,您的应用程序可以使用它。但是,建议您连接到您应用程序的事件系统

在提供的调度器中,您可以通过为以下列出的事件注册可调用函数来监听事件,这些可调用函数将在事件引发时触发。

// @see Resque\Component\Core\Event\EventDispatcher
$dispatcher->addListener('eventName', [callback]);

[回调]可以是 PHP 中的任何可调用的内容。

事件对象作为单个参数传递(下面有说明)。

您可以通过调用带有与 EventDispatcher->addListener 相同参数的 EventDispatcher->removeListener 来停止监听事件。

事件

在 php-resque 中,每个事件都是一个具有名称的对象,根据情况可能还有其他属性。以下列表显示了每个事件名称及其相关联的对象。至少所有事件对象都将实现 Resque\Event\EventInterface 接口。

resque.worker.start_up

@see Resque\Component\Worker\Event\WorkerEvent

在初始化工作进程时引发一次。传递的参数是刚刚初始化的 Worker 实例。

resque.worker.before_fork

@see Resque\Event\WorkerBeforeForkEvent

Resque\Component\Worker\Worker 分叉以运行作业之前引发。该事件包含即将执行的 WorkerResque\Component\Job\Model\Job

resque.job.before_fork父进程 中引发。任何更改将永久保留,直到 工作进程 生存期结束。

resque.worker.after_fork

@see Resque\Event\WorkerAfterForkEvent

从子进程引发,在 Resque\Component\Worker\Worker 分叉以运行作业后(但在运行作业之前)。该事件包含即将执行的 WorkerResque\Component\Job\Model\Job

注意: resque.job.before_fork 在分叉出以完成作业的 子进程 中引发。任何更改将仅在作业处理期间保留。

resque.job.before_perform

@see Resque\Event\JobBeforePerformEvent

在调用作业上的 perform 方法之前引发。该事件包含即将执行的 Resque\Component\Job\Model\Job 实例以及将要调用 perform 方法的目标类实例。

抛出的任何异常都将被视为在作业中抛出,导致作业被标记为失败。

resque.job.after_perform

@see Resque\Event\WorkerAfterForkEvent

在作业成功执行后立即引发。该事件包含 Resque\Component\Job\Model\Job 实例和刚刚执行的实例。

抛出的任何异常都将被视为在作业中抛出,导致作业被标记为失败。

resque.job.failed

@see Resque\Component\Job\Event\JobFailedEvent

每次作业执行失败时都会引发。也就是说,当作业抛出异常或工作进程的子进程未能干净地退出时。

该事件包含以下内容:

  • Resque\Component\Job\Model\Job 刚刚失败的作业。
  • Resque\Component\Worker\Worker 作业刚刚失败的作业所在的工作进程。
  • \Exception 当作业失败时抛出的异常,如果抛出异常导致作业失败。

afterEnqueue

在通过 Resque::enqueue 方法将作业排队后调用。按此顺序传递的参数包括

  • 类 - 包含计划作业名称的字符串
  • 参数 - 传递给作业的参数数组
  • RedisQueue - 包含添加作业的队列名称的字符串
  • ID - 包含已排队作业新令牌的字符串

分发器替换

// @todo 文档化使用