CakePHP:从控制器运行shell作业

web*_*jay 8 shell cakephp

是否可以从Controller使用dispatchShell?

我的任务是在用户注册时启动shell作业.

我正在使用CakePHP 2.0

dei*_*zel 13

如果你不能像教条所暗示的那样减少这样做的需要,请继续阅读.

因此,您希望执行(可能)长时间运行的作业,并且您不希望用户等待.

由于用户正在执行的PHP代码发生在Apache启动的请求期间,所执行的任何代码都将停止该请求直到完成(除非您点击Apache的请求超时).

如果您的应用程序无法接受上述内容,那么您将需要在Apache请求之外触发PHP(即从命令行).

可用性方面,此时通知您的用户您正在后台处理数据是有意义的.来自消息的任何消息告诉他们,他们可以稍后再回到旋转的进度条,该进度条通过ajax轮询您的应用程序以检测作业完成情况.

最简单的方法是让cronjob在某个时间间隔内执行PHP脚本(即CakePHP shell)(至少每分钟一次).在这里,您可以在后台执行此类任务.

但是,后台工作会出现一些问题.你怎么知道他们什么时候失败了?你怎么知道什么时候需要重试?如果它没有在cron间隔内完成怎么办?会出现竞争条件吗?

正确但更复杂的设置是使用工作/消息队列系统.它们允许您更优雅地处理上述问题,但通常要求您在服务器上运行后台守护程序以捕获和处理任何传入的作业.

它的工作方式是,在您的代码中(当用户注册时),您将作业插入队列.队列守护程序立即获取作业(它不会间隔运行,因此它总是在等待)并将其交给工作进程(例如CakePHP shell).它是即时的 - 如果你告诉它 - 它知道它是否有效,它知道它是否失败,它可以重试,如果你想要它并不会意外地处理相同的工作两次.

有许多可用的,如Beanstalkd,dropr,Gearman,RabbitMQ等.还有一些CakePHP插件(不同年龄)可以帮助:

我有使用CakePHP和Beanstalkd(+ PHP Pheanstalk库)和CakePHP Queue插件(上面的第一个)的经验.我必须赞扬Beanstalkd(用C语言编写)非常轻巧,简单和快速.但是,关于CakePHP开发,我发现插件启动和运行的速度更快,因为:

  • 该插件附带了入门所需的所有PHP代码.使用Beanstalkd,您需要编写更多代码(例如轮询队列以查找作业的PHP守护程序)
  • Beanstalkd服务器基础架构变得更加复杂.我不得不beanstalkd为dev/test/prod 安装多个实例,并安装supervisord以查看进程).
  • 开发/测试更容易,因为它是一个独立的CakePHP + MySQL解决方案.你只需要输入cake queue add user signupcake queue runworker.


Lub*_*lík 9

我能够从控制器/动作运行consolle,请参阅下面的示例.

App::uses('ShellDispatcher', 'Console');
...
public function aco_sync() {
    $command = '-app '.APP.' AclExtras.AclExtras aco_sync -r adminControllers -p UserAdmin';
    $args = explode(' ', $command);
    $dispatcher = new ShellDispatcher($args, false);
    if($dispatcher->dispatch()) {
        $this->Session->flash('OK');
    } else {
        $this->Session->flash('Error');
    }
    return $this->redirect(array('action' => 'index'));
}
Run Code Online (Sandbox Code Playgroud)