0

我目前有以下内容:

try {
    $pheanstalk->useTube($tube)->put($data);
} catch (\Exception $e) {
    $logger = $this->container->get('logger');
    $logger->info('Could not reach beanstalk: ' . $e);
}

这工作正常,但我希望它$pheanstalk->useTube($tube)->put($data)不等待来自服务器的连接响应,并且只会尝试将数据放在队列中,然后继续以愉快的方式继续。该服务存储的数据很不错,但并不重要。因此,在重负载期间,我希望不必等待超时时间才能继续执行程序的其余部分。如何消除等待 pheanstalk 的服务器部分的响应?

4

1 回答 1

0

为防止阻塞,您必须分叉您的进程。

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     // proceed with whatever
} else {
     // we are the child
     $exitStatus = -1;
     try {
         $pheanstalk->useTube($tube)->put($data);
         $exitStatus = 1;
     } catch (\Exception $e) {
         $logger = $this->container->get('logger');
         $logger->info('Could not reach beanstalk: ' . $e);
         $exitStatus = 0;
     }

     exit($exitStatus); 
}

这样做是分叉你的进程并让子进程等待直到 pheanstalk 返回。请注意,还有一些其他问题:

  • 如果 pheanstalk 永远不会回来怎么办?你的子进程变成了僵尸。
  • 分叉一个流程包括复制大量流程变量。这并非没有开销,因此不一定会减少您的负载。如果您之后所做的一切都是真正的工作,那么这可能是值得的。

理论上,您可以将消息传递到本地排队系统,在同一个盒子上,它的工作是将消息放在远程系统上。这将使您获得相当快的响应,但可能需要您进行更多的编码。但是,如果您已经有一个本地 beanstalk 实例,那么这将无济于事。(我怀疑你没有;本地呼叫 beanstalk 很快。如果你有本地电话,问题可能出在工人/消费者端。)

于 2013-06-19T23:19:56.780 回答