instasent/resque-bundle

InstasentResqueBundle

v0.2.5 2021-11-30 13:50 UTC

This package is not auto-updated.

Last update: 2024-09-18 03:32:56 UTC


README

这是一个从 https://github.com/michelsalib/InstasentResqueBundle 分支出来的版本,以便保持其维护。

Instasent resque bundle 为 Symfony 提供了 php-resque 的集成。它受到 resque 的启发,这是一个基于 Redis 的 Ruby 库,用于创建后台作业,将它们放置在多个队列中,并在稍后进行处理。

特性

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

待办事项

  • 日志管理
  • 作业状态跟踪
  • Redis 配置
  • 本地化
  • 测试

屏幕截图

仪表板

安装和配置

要求

确保您的机器上已安装 redis: https://redis.ac.cn/

获取包

instasent-resque-bundle 添加到您的依赖项中

{
    "require": {
        ...
        "instasent/resque-bundle": "dev-master"
    }
    ...
}

要安装,运行 php composer.phar [update|install]

将 InstasentResqueBundle 添加到您的应用程序内核

<?php

    // app/AppKernel.php
    public function registerBundles()
    {
        return array(
            // ...
            new Instasent\ResqueBundle\InstasentResqueBundle(),
            // ...
        );
    }

导入路由配置

routing.yml 添加到您的配置中

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

您可以根据需要自定义前缀。

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

为了保护仪表板,您可以在 security.yml 中添加以下内容 - 如果您的管理员角色是 ROLE_ADMIN

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

可选,通过角色保护仪表板

security.yml 添加到您的配置中

# app/config/security.yml
access_control:
    - { path: ^/resque, roles: ROLE_ADMIN }

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

可选,设置配置

您可能希望向您的 config.yml 添加一些配置

# app/config/config.yml
instasent_resque:
    class: Instasent\ResqueBundle\Resque           # the resque class if different from default
    vendor_dir: %kernel.root_dir%/../vendor  # the vendor dir if different from default
    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
    auto_retry: [0, 10, 60]                  # auto retry failed jobs
    worker:
        root_dir: path/to/worker/root        # the root dir of app that run workers (optional)

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

如果工作进程系统托管在创建队列的系统之外的独立服务器/目录中,则在作业失败运行时设置 worker: root_dir:。当运行多个配置的应用程序为多个工作进程时,所有应用程序都必须能够通过在 worker: root_dir 中定义的相同 root_dir 访问。

可选,配置延迟加载

此包已准备好进行延迟加载,以便仅在真正需要时才连接到 Redis。Symfony2 从 2.3 版本开始支持。为了使其生效,需要执行一个额外的步骤。您需要将代理管理器安装到您的 Symfony2 项目中。有关添加代理管理器的完整文档,请参阅 Symfony2 的延迟服务文档

创建作业

工作是一个Instasent\ResqueBundle\Job类的子类。如果需要在工作执行期间利用容器,您也可以使用Instasent\Resque\ContainerAwareJob。您将被迫实现包含您工作逻辑的run方法。

<?php

namespace My;

use Instasent\ResqueBundle\Job;

class MyJob extends Job
{
    public function run($args)
    {
        \file_put_contents($args['file'], $args['content']);
    }
}

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

将工作添加到队列

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

<?php

// get resque
$resque = $this->get('instasent_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 instasent:resque:worker-start default
  • q1q2队列:app/console instasent:resque:worker-start q1,q2(使用,分隔名称)
  • 所有现有队列:app/console instasent:resque:worker-start "*"

您还可以通过添加--foreground选项在后台运行工作;

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

  • --verbose选项设置VVERBOSE
  • --quiet禁用两者,因此不会抛出调试输出

请参阅php-resque日志选项:[https://github.com/chrisboulton/php-resque#logging](https://github.com/chrisboulton/php-resque#logging)

从您的内核使用monolog

您可以将monolog通道传递给写入日志,请参阅supervisor配置中的示例。注意:将Kernel ENV传递给resque是为了实例化logger,而不是为了在作业之间共享kernel。

在不进行分叉的情况下运行工作

有时,在分叉模式下,密集型任务可能会失去性能。我们添加了bin/resque-single二进制文件,您可以将仅启动时加载一次的kernel文件传递。请小心,因为如果这个Worker失败,那么您需要手动重新启动这个Worker。我们建议使用supervisor来控制它,并使用带有内存插件的superlance在达到某些内存阈值时重新启动工作。也要注意您的代码、共享变量、服务实例等。

将延迟工作添加到队列

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

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

<?php

// get resque
$resque = $this->get('instasent_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);

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

app/console instasent:resque:scheduledworker-start

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

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

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

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

使用supervisord管理生产工作

最好使用supervisord([http://supervisord.org](http://supervisord.org))在生产中运行工作,而不是重新发明作业生成、监控、停止和重新启动。

以下是一个示例配置文件

[program:myapp_phpresque_default]
command = /usr/bin/php /home/sites/myapp/prod/current/vendor/instasent/resque-bundle/Instasent/ResqueBundle/bin/resque
user = myusername
environment = APP_INCLUDE='/home/sites/myapp/prod/current/vendor/autoload.php',VERBOSE='1',QUEUE='default'
stopsignal=QUIT

[program:myapp_phpresque_default_single_worker]
command = /usr/bin/php /home/sites/myapp/prod/current/vendor/instasent/resque-bundle/Instasent/ResqueBundle/bin/resque-single
user = myusername
environment = APP_KERNEL='/home/sites/myapp/prod/current/app/AppKernel.php',APP_INCLUDE='/home/sites/myapp/prod/current/vendor/autoload.php',VERBOSE='1',QUEUE='default'
stopsignal=QUIT

[program:myapp_phpresque_scheduledworker]
command = /usr/bin/php /home/sites/myapp/prod/current/vendor/instasent/resque-bundle/Instasent/ResqueBundle/bin/resque-scheduler
user = myusername
environment = APP_INCLUDE='/home/sites/myapp/prod/current/vendor/autoload.php',VERBOSE='1',RESQUE_PHP='/home/sites/myapp/prod/current/vendor/chrisboulton/php-resque/lib/Resque.php'
stopsignal=QUIT

[program:myapp_phpresque_default_single_worker_logger]
command = /usr/bin/php /home/sites/myapp/prod/current/vendor/instasent/resque-bundle/Instasent/ResqueBundle/bin/resque-single
user = myusername
environment = APP_KERNEL='/home/sites/myapp/prod/current/app/AppKernel.php',LOG_CHANNEL='monolog.logger.custom',APP_INCLUDE='/home/sites/myapp/prod/current/vendor/autoload.php',VERBOSE='1',QUEUE='default'
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 Instasent\ResqueBundle\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';

从您的作业内部访问容器

只需扩展ContainerAwareJob

<?php

namespace My;

use Instasent\ResqueBundle\ContainerAwareJob;

class MyJob extends ContainerAwareJob
{
    public function run($args)
    {
        $doctrine = $this->getContainer()->getDoctrine();
        ...
    }
}

停止一个工作

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

  • 没有参数将显示您可以选择停止的正在运行的工作。
  • 添加一个工作ID来停止它:app/console instasent:resque:worker-stop ubuntu:3949:default
  • 添加--all选项来停止所有工作。

自动重试

您可以为特定作业或所有作业添加重试策略,以便让任务包自动重试失败的作业。

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

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

为所有作业设置策略

instasent_resque:
    auto_retry: [0, 10, 60]

除特定作业外,使用默认策略

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

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

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

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

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

请注意

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

app/console instasent:resque:scheduledworker-start