用于管理Resque任务队列的Symfony 4扩展包

安装次数: 115 506

依赖者: 1

建议者: 0

安全性: 0

星星: 50

关注者: 5

分支: 29

开放性问题: 5

类型:symfony-bundle

5.0.3 2021-09-30 10:49 UTC

README

Scrutinizer Code Quality

该项目已不再进行任何开发(最后重大更新日期:2021年9月)

如果您想接管此项目的维护,请联系phil@phil-taylor.com - 我不再在任何一个实际项目中使用这里的代码,因为我转向了Symfony Messenger,使用Redis来满足我自己的队列需求。

如果您使用的是PHP 8,请查看php8分支以获取最新稳定版本

ResqueBundle

兼容性

  • 对于Symfony 5+,请使用ResqueBundle v4.0.0+
  • 对于Symfony 4+,请使用主系列ResqueBundle v3+,并着手进行Symfony 5迁移;-)
  • 对于Symfony 3+,请将ResqueBundle v2.0.9+与精确版本绑定,并考虑是否继续使用Symfony 3

请注意,我们不提供与symfony本身相同的b/c promise,但我们尽力为每个主要的symfony版本推出主要版本。

2020年5月更新

  • 在命令和控制台中注入ParameterBagInterface而不是直接访问容器
  • 使用kernel.project_dir代替kernel.root_dir(因为破坏性更改!您需要更新您的config yml配置)
  • 更新路由控制器以使用长语法
  • 使用@Bundle语法加载twig模板
  • 为关键安全性强制使用最低的Symfony 4.1.2版本
  • 使用正确的Process函数以获得最大兼容性
  • 完全放弃对Symfony 3.4的支持,抱歉。

2019年11月更新

我现在已经在master分支上进行了工作,以实现与Symfony 4+的兼容性,使用依赖注入代替ContainerAwareJob

如果您仍在使用Symfony 3,那么您必须将composer.json绑定到2.0.9版本

此捆绑包的第一个版本与3.0.0版本高度兼容且积极维护

如果您以前使用过此捆绑包,并且想要更新到最新版本,那么您需要

  • 升级到此捆绑包的3.0.0+版本
  • 使用Symfony 4(我目前使用4.4.0RC1)
  • 将您的任务更改为扩展ResqueBundle\Resque\Job而不是ContainerAwareJob
  • 添加__construct方法以注入您的依赖项
  • 从您的任务中移除所有对容器或getContainer的引用
  • 享受吧!

ResqueBundle历史

这是一个BCCResqueBundle的分叉版本,因为*那个捆绑包不再积极维护。该项目中有许多悬而未决的问题、拉取请求和错误需要修复,但没有活动,所以我们进行了分叉,并将在这个仓库中积极支持和发展代码。

这也是将Mpclarkson\ResqueBundle重新命名为将代码置于GitHub组织下的一个举措,以确保未来的分布式开发

欢迎贡献力量

resque捆绑包提供php-resque与Symfony4的集成。它受到resque的启发,resque是一个Redis支持的Ruby库,用于创建后台任务,将它们放入多个队列,并在以后处理它们。

功能

  • 创建一个具有容器访问权限的作业,以便利用您的Symfony服务
  • 在指定的队列上入队一个带有参数的作业
  • 在指定队列上创建后台工作进程
  • 一个用于监控您的队列、工作进程和作业状态的接口
  • 安排在特定时间或延迟数秒后运行的作业
  • 自动重新入队失败的作业,并采用回退策略
  • 依赖注入到作业

安装和配置

需求

Symfony 4+

获取软件包

要安装,请运行 composer req resquebundle/resque

导入路由配置

将以下内容添加到 routing.yml

# app/config/routing.yml
ResqueBundle:
    resource: "@ResqueBundle/Resources/config/routing.xml"
    prefix:   /resque

您可以按需自定义前缀。

您现在可以通过此URL访问仪表板:/resque

为了保护仪表板,您可以将以下内容添加到您的 security.yml 中,假设您的管理员角色为 ROLE_ADMIN

access_control:
  - { path: ^/resque, roles: ROLE_ADMIN }

现在只有具有角色 ROLE_ADMIN 的用户才能访问此 URL 的仪表板:/resque

可选,设置配置

您可能想要向您的 config.yml 添加一些配置。

# app/config/config.yml
resque:
    app_include: /pathto/bootstrap.php.cache # app include file if different from default (i.e. /var/bootstrap.php.cache)
    prefix: my-resque-prefix                 # optional prefix to separate Resque data per site/app
    redis:
        host: localhost                      # the redis host
        port: 6379                           # the redis port
        database: 1                          # the redis database
        password: ~                          # the redis password, defaults to null
    auto_retry: [0, 10, 60]                  # auto retry failed jobs
    worker:
        project_dir: path/to/worker/project_dir        # the project_dir of app that run workers (optional)

有关如何使用 auto_retry 的更多信息,请参阅 自动重试 部分。

如果工作进程系统托管在与创建队列的系统分开的服务器/目录上,请设置 worker: project_dir: 以便在作业失败时运行。当运行多个配置的应用程序为多个工作进程提供服务时,所有应用程序都必须能够通过在 worker: root_dir 中定义的同一根目录访问。

创建一个作业

作业是 ResqueBundle\Resque\Job 类的子类。

您必须实现包含作业逻辑的运行方法。

<?php

namespace My;

use ResqueBundle\Resque\Job;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;

class MyJob extends Job
{
    /**
     * @var string The queue name
     */
    public $queue = 'myqueue';

    /**
     * @var ManagerRegistry
     */
    private $registry;
    
    /**
     * @var ObjectManager
     */
    private $em;

    /**
     * Use the __construct to inject your dependencies
     *
     * @param array           $args
     * @param ManagerRegistry $registry
     */
    public function __construct(
        $args = [],
        ManagerRegistry $registry
    ) {
        $this->registry      = $registry;
        $this->em            = $registry->getManager();
        parent::__construct($args);
    }

    public function run($args)
    {
        file_put_contents($args['file'], $args['content']);
    }
}

如您所见,您将获得一个 $args 参数,它是作业的参数数组。

将作业添加到队列

您可以通过容器获取 resque 服务。从您的控制器中,您可以这样做

<?php

// get resque (only if service has been made public - else USE DI LIKE YOU SHOULD)
// $resque = $this->get('ResqueBundle\Resque\Resque');

// create your job
$job = new MyJob();
$job->args = array(
    'file'    => '/tmp/file',
    'content' => 'hello',
);

// enqueue your job
$resque->enqueue($job);

在队列上运行工作进程

执行以下命令将在 default 队列上创建工作: app/console resque:worker-start default

  • q1q2 队列上: app/console resque:worker-start q1,q2(使用逗号分隔名称)
  • 在所有现有队列上: app/console resque:worker-start "*"
  • 您也可以通过添加 --foreground 选项以前台模式运行工作进程;

默认情况下,在调用 php-resque 时会设置 VERBOSE 环境变量

--verbose 选项设置 VVERBOSE

将延迟作业添加到队列

您指定作业在特定时间运行或在特定延迟(以秒为单位)后运行。

从您的控制器中,您可以这样做

您还必须运行一个 scheduledworker,它负责从特殊的延迟队列中取出项并将它们放入最初指定的队列。

<?php

// get resque (only if service has been made public - else use DI LIKE YOU SHOULD)
//$resque = $this->get('ResqueBundle\Resque\Resque');

// create your job
$job = new MyJob();
$job->args = array(
    'file'    => '/tmp/file',
    'content' => 'hello',
);

// enqueue your job to run at a specific \DateTime or int unix timestamp
$resque->enqueueAt(\DateTime|int $at, $job);

// or

// enqueue your job to run after a number of seconds
$resque->enqueueIn($seconds, $job);

使用 app/console resque:scheduledworker-start

稍后使用 app/console resque:scheduledworker-stop 停止它。

请注意,在后台模式下运行时,它会在 'cache//resque_scheduledworker.pid' 中创建一个 PID 文件。如果您在 scheduledworker 运行时清除缓存,您将无法使用 scheduledworker-stop 命令停止它。

或者,您可以使用 --foreground 选项在前台模式下运行 scheduledworker。

请注意,您应该始终只运行一个 scheduledworker,如果 PID 文件已存在,您必须使用 --force 选项来启动 scheduledworker。

请注意,您应该始终只运行一个 scheduledworker,如果 PID 文件已存在,您必须使用 --force 选项来启动 scheduledworker。

使用 supervisord 管理生产工作进程

在生产和重新发明作业生成、监控、停止和重新启动方面,最好使用 supervisord (http://supervisord.org) 来运行工作进程。

以下是一个示例配置文件

[program:myapp_phpresque_default]
command = /usr/bin/php /home/sites/myapp/bin/console resque:worker-start high --env=prod --foreground --verbose
user = myusername
stopsignal=QUIT

[program:myapp_phpresque_scheduledworker]
command = /usr/bin/php /home/sites/myapp/prod/bin/console resque:scheduledworker-start --env=prod --foreground --verbose
user = myusername
stopsignal=QUIT

[group:myapp]
programs=myapp_phpresque_default,myapp_phpresque_scheduledworker

(如果您使用自定义的Resque前缀,请添加额外的环境变量:PREFIX='my-resque-prefix')

然后在Capifony中您可以这样做

sudo supervisorctl stop myapp:* 在部署应用程序之前,并在之后执行sudo supervisorctl start myapp:*

更多功能

更改队列

您可以通过设置作业的queue字段来更改作业队列

在作业内部

<?php

namespace My;

use ResqueBundle\Resque\Job;

class MyJob extends Job
{
    public function __construct()
    {
        $this->queue = 'my_queue';
    }

    public function run($args)
    {
        ...
    }
}

或在作业外部

<?php

// create your job
$job = new MyJob();
$job->queue = 'my_queue';

停止工作进程

使用app/console resque:worker-stop命令。

  • 没有参数将显示可以停止的运行中的工作进程。
  • 添加工作进程ID以停止它:app/console resque:worker-stop ubuntu:3949:default
  • 添加--all选项以停止所有工作进程。

自动重试

您可以通过为特定作业或所有作业添加重试策略来自动重试失败的任务

以下设置将允许Some\Job重试3次。

  • 立即
  • 延迟10秒后
  • 延迟60秒后
resque:
    redis:
        ....
    auto_retry:
        Some\Job: [0, 10, 60]

为所有作业设置策略

resque:
    auto_retry: [0, 10, 60]

除了特定作业外的默认策略

resque:
    auto_retry:
    	default:        [0, 10, 60]
        Some\Job:       [0, 10, 120, 240]
        Some\Other\Job: [10, 30, 120, 600]

default策略(如果提供)将应用于没有附加特定策略的所有作业。如果没有提供,这些作业将不会自动重试。

您可以使用空数组禁用选定作业的auto_retry

resque:
    auto_retry:
    	default:        [0, 10, 60]
        Some\Job:       []
        Some\Other\Job: [10, 30, 120, 600]

在这里,Some\Job将不会有任何auto_retry附加。

请注意

要使用auto_retry功能,您还必须运行调度程序作业

稍后使用 app/console resque:scheduledworker-stop 停止它。