这是一个老问题,可能你已经解决了......无论如何,这里有一个简短的答案和更详细的解释:
TL;DR:简短回答:问题是,您在 put() 方法中运行 (cpu/disk io) 密集型代码,并且您需要在 $job->getData() 之后在工作程序中运行它。
说明:
Beanstalk充当消息队列,并允许您将信息生产者与消费者分离。这个想法是您只需将您想要完成的工作的描述发布到队列中,然后生成该描述并将其发布到队列中非常快。实际的资源(CPU/RAM/磁盘IO/网络)消耗处理发生在消费者(工作者)中,当有可用的资源时,生产者可以自由地做其他事情。如果没有可用的工人,那么作业将堆积在队列中。
因此,在您的情况下,例如,将您的生产者和消费者分开到 Chief.php 和 worker.php:
首席.php
<?php
require_once('pheanstalk_init.php');
$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');
$pheanstalk
->useTube('testtube')
->put("cat ../uploads/databases/app_data/Filename.sql | sqlite3 ../uploads/databases/Filename.sqlite");
?>
工人.php:
<?php
require_once('pheanstalk_init.php');
$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');
while(true){
$job = $pheanstalk->watch('testtube')->ignore('default')->reserve();
$cmd = $job->getData();
exec($cmd);
$pheanstalk->delete($job);
}
?>
所以,当你运行一个 worker 时,它会连接到beanstalkd服务器,并等待一个作业发布到 'testtube' queue/tube 上。然后它将执行所描述的工作,并将其从队列中删除,然后循环,准备好处理另一个工作,当它到达时。如果需要,您也可以并行运行多个工作程序。
注意:beantalkd服务器不运行您的工人;它只将工作从生产者分配给消费者。所以你需要自己管理正在运行的工作进程。我个人更喜欢将workers作为runit服务运行,这样当它们出现任何问题时,它们会被runit重新启动,并且它们的输出会被记录下来。您当然可以使用任何您喜欢的进程监控工具:runit、systemd、monit等...
在你最喜欢的进程监视器下运行beanstalkd本身也是一个好主意,以防它崩溃,这不太可能发生,但可能发生(它在一年前发生在我身上)。