【问题标题】:pheanstalk useTube()->put() function, don't wait for responsepheanstalk 使用Tube()->put() 函数,不等待响应
【发布时间】:2013-03-04 18:07:24
【问题描述】:
我目前有以下:
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 的服务器部分的响应?
【问题讨论】:
标签:
php
asynchronous
pheanstalk
【解决方案1】:
为防止阻塞,您必须分叉您的进程。
$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 很快。如果你有本地电话,问题可能出在工人/消费者端。)