giovanne-oliveira/php-resque

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

3.1.1 2023-02-08 10:14 UTC

README

php-resque(发音为“rescue”)是一个基于Redis的库,用于创建后台任务,将这些任务放入多个队列,并在以后处理它们。

内容

背景

此版本的php-resque基于最初由chrisboulton完成的工作,他将同名ruby版本移植过来,该版本由GitHub创建。

重新编写之前工作的原因是为了添加更好的支持工作者服务器的水平扩展,并提高任务失败容错性,以创建一个非常高可用的系统。与Monolog的集成意味着可以实现非常详细的日志记录,这使得解决分布式系统中的错误变得容易得多。广泛的事件/钩子系统可以实现更深入的集成和统计收集。

此版本提供了以下功能:

  • 工作者可以在多台机器之间分布。
  • 具有抵抗内存泄漏的能力(任务在分叉进程中运行)。
  • 期望并记录失败。
  • 使用Monolog进行日志记录。
  • 可以将闭包推送到队列中。
  • 跟踪任务状态和输出。
  • 如果超出内存或最大执行时间,任务将干净地失败。
  • 如果一个运行任务的分叉子进程没有以状态码0退出,则将任务标记为失败。
  • 具有内置事件系统,可启用钩子以实现深层集成。
  • 支持优先级(队列)。

此版本不是直接从Github的Resque移植过来,因此与它不兼容,也不与其Web界面兼容。 可以在GitHub上找到为此版本构建的基于Symfony 3.x的Resque Web界面。

要求

要运行php-resque,您必须安装以下内容

可选,但推荐

入门

在项目中以Composer包的形式安装php-resque是最容易的方式。虽然Composer不是必需的,但它可以使生活变得更简单。

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

{
    "require": {
        "mjphaynes/php-resque": "3.1.*"
    }
}

导航到项目根目录并运行

$ php composer.phar install

如果您尚未这样做,请将Composer自动加载器添加到项目的引导中

require 'vendor/autoload.php';

任务

定义任务

每个任务应在其自己的类中,并包含一个perform方法。

class MyJob {

    public function setUp() {
        // Set up environment for this job
    }

	public function perform($args) {
        // Perform some job
    }

    public function tearDown() {
        // Remove environment for this job
    }

}

当运行任务时,将实例化该类,并将任何参数作为参数发送到perform方法。当前任务实例(Resque\Job)作为第二个参数传递给perform方法。

任务抛出的任何异常都将导致任务失败 - 这里要小心,确保你处理那些不应当导致任务失败的异常。如果你想取消一个任务(而不是让它失败),可以抛出一个Resque\Exception\Cancel异常,该任务将被标记为已取消。

任务还可以拥有setUptearDown方法。如果定义了setUp方法,它将在执行方法运行之前被调用。如果定义了tearDown方法,它将在任务完成后被调用。如果在setUp方法中抛出异常,则不会执行执行方法。这在具有不同任务但需要相同引导过程(例如数据库连接)的情况下非常有用。

排队任务

要向队列添加新任务,请使用Resque::push方法。

$job = Resque::push('MyJob', array('arg1', 'arg2'));

第一个参数是你任务类的完整解析后的类名(如果你想知道php-resque是如何知道你的任务类的,请参阅自动加载任务类)。第二个参数是你想要传递给任务类的任何参数的数组。

也可以将闭包推送到队列。这对于需要快速、简单的任务且需要排队的情况非常方便。当将闭包推送到队列时,不应使用__DIR____FILE__常量。

$job = Resque::push(function($job) {
    echo 'This is a inline job #'.$job->getId().'!';
});

可以通过传递第三个参数到Resque::push方法(包含队列名称)将任务推送到另一个队列(默认队列称为default)。

$job = Resque::push('SendEmail', array(), 'email');

延迟任务

可以使用Resque::later方法安排任务在未来的指定时间运行。你可以通过传递一个intDateTime对象来完成此操作。

$job = Resque::later(60, 'MyJob', array());
$job = Resque::later(1398643990, 'MyJob', array());
$job = Resque::later(new \DateTime('+2 mins'), 'MyJob', array());
$job = Resque::later(new \DateTime('2014-07-08 11:14:15'), 'MyJob', array());

如果你传递一个整数,并且它小于94608000秒(3年),php-resque将假设你想要相对于当前时间的时间(毕竟,谁会延迟超过3年的任务呢?)。请注意,你必须有一个在指定时间运行的工作进程,以便任务可以运行。

任务状态

php-resque跟踪任务的状态。状态信息将允许你检查任务是否在队列中,目前正在运行,失败等。要跟踪任务的状态,你必须捕获已推送任务的作业ID。

$job = Resque::push('MyJob');
$jobId = $job->getId();

要获取任务的状态

$job = Resque\Job::load($jobId);
$status = $job->getStatus();

作业状态定义为Resque\Job类中的常量。有效的状态是

  • Resque\Job::STATUS_WAITING - 作业仍在队列中
  • Resque\Job::STATUS_DELAYED - 作业已延迟
  • Resque\Job::STATUS_RUNNING - 作业目前正在运行
  • Resque\Job::STATUS_COMPLETE - 作业已完成
  • Resque\Job::STATUS_CANCELLED - 作业已被取消
  • Resque\Job::STATUS_FAILED - 作业已失败
  • false - 无法获取状态 - ID是否有效?

状态在作业完成后或失败后7天内可用,然后自动过期。此超时可以在配置文件中更改。

工作者

要启动工作进程,请导航到您的项目根目录并运行

$ bin/resque worker:start

请注意,一旦此工作进程启动,它将一直运行,直到手动停止。您可以使用进程监视器(例如Supervisor)将工作进程作为后台进程运行,并确保工作进程不会停止运行。

如果工作进程是后台任务,您可以使用以下命令停止、暂停和重新启动工作进程

$ bin/resque worker:stop
$ bin/resque worker:pause
$ bin/resque worker:resume

这些命令接受内联配置选项,并从配置文件读取。

例如,要指定工作进程仅处理名为highlow的队列上的作业,以及允许作业的最大内存为30MB,您可以运行以下命令

$ bin/resque worker:start --queue=high,low --memory=30 -vvv

请注意,这将首先检查high队列,然后是low队列,因此可以使用此方法来方便地设置作业队列的优先级。要运行所有队列,请使用* - 这是默认值。使用-vvv启用非常详细的日志记录。要关闭任何日志,请使用-q标志。

有关更多命令和完整选项列表,请参阅命令文档

此外,如果工作进程在另一台主机上运行,您可以通过Redis中的数据远程触发工作进程的优雅关闭。例如

foreach(Resque\Worker::allWorkers() as $worker) {
    $worker->shutdown();
}

信号

信号在支持的平台上是有效的。发送给工作进程的信号将产生以下效果

  • QUIT - 等待子进程完成处理然后退出
  • TERM / INT - 立即杀死子进程然后退出
  • USR1 - 立即杀死子进程但不退出
  • USR2 - 暂停工作进程,不会处理新作业
  • CONT - 恢复工作进程

分叉

当php-resque运行一个作业时,它首先将进程分叉到子进程中。这样做是为了如果作业失败,工作进程可以检测到作业失败,并且将继续运行。分叉的子进程将在作业完成时立即退出。

要使用php-resque,必须安装PECL模块(https://php.ac.cn/manual/en/book.pcntl.php)。

进程标题

更新工作进程的进程标题非常有用,因为它可以指示工作进程正在做什么,并且任何分叉的子进程也将使用正在运行的作业设置其进程标题。这有助于识别服务器上运行的过程及其php-resque状态。

不幸的是,PHP默认没有安装更新进程标题的能力。

存在一个PECL模块(http://pecl.php.net/package/proctitle),可以向PHP添加此功能,因此如果您想更新进程标题,请同时安装此PECL模块。php-resque将检测并使用它。

自动加载任务类

启动应用程序还需要通过自动加载器或包含它们来告诉工作进程您的作业类。如果您使用Composer,则在那里添加您的作业类相对简单。

或者您可以在config.yml文件中或通过设置包含参数来完成此操作

$ bin/resque worker:start --include=/path/to/your/include/file.php

此项目中examples/文件夹中有一个如何实现所有这些的示例。

命令和选项

有关php-resque命令及其相关参数的完整列表,请参阅命令文档

日志记录

php-resque与Monolog集成,这为日志记录提供了广泛的能力。有关完整文档,请参阅日志记录文档

事件/钩子系统

php-resque有一个广泛的事件/钩子系统,允许开发者在不修改任何核心文件的情况下深度集成库。有关完整文档和所有事件的列表,请参阅钩子文档

配置选项

有关所有配置选项的完整列表,请参阅配置文档

Redis

您可以将Redis连接细节直接设置或设置在配置文件中。在运行命令时设置

$ bin/resque [command] --host=<hostname> --port=<port>

贡献

PHP-Resque v3适用于PHP 7.1或更高版本,新代码必须与PHP 7.1兼容。大部分代码库仍然是针对PHP 5的,但欢迎PR以升级代码。尽可能遵循PSR-2编码风格。新功能应附带测试。

贡献者

为项目做出贡献将对维护和扩展脚本有极大的帮助。如果您有兴趣贡献力量,请在Github上发起一个pull request。