【问题标题】:PHP multiprocessing with cronjob using CURL使用 CURL 的 cronjob 的 PHP 多处理
【发布时间】:2012-06-19 19:49:43
【问题描述】:

我需要做的是使用 PHP 处理数据库中待处理的多个请求。

我目前正在尝试做的是: 当我的 cronjob 运行时。我想立即调用文件“process_a.php”10 次,而无需等待它完成处理(process_a.php 可能需要几分钟)。

我尝试使用 CURL 来做到这一点。但是当我的 cronjob 调用 process_a.php 时,它会等待它完成处理并在调用另一个 process_a.php 文件之前返回。

我什至尝试将代码放入 process_a.php 以立即关闭连接,然后在后台继续处理。但 cronjob 仍在等待它完成。

我只想让同一个文件一次执行 10 次,就像 10 个不同的用户请求我网站的 index.php 页面一样... 有什么想法!?

【问题讨论】:

标签: php multithreading curl cron multiprocessing


【解决方案1】:

正如@Brad curl-multi-exec 所说,应该是一个选项。

http://php.net/manual/en/function.curl-multi-exec.php

    <?php
//create the multiple cURL handle
$mh = curl_multi_init();

// create both cURL resources
for($i = 0; $i < 10;$i++){
     $ch[$i] = curl_init();
     curl_setopt($ch[$i], CURLOPT_URL, "http://urhost//path/to/process_a.php");
     curl_setopt($ch[$i], CURLOPT_HEADER, 0);
     curl_multi_add_handle($mh,$ch[$i]);//add the handles
}

$active = null;

//execute the handles
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

//close the handles
for($i = 0; $i < 10;$i++){
     curl_multi_remove_handle($mh, $ch[$i]);
}
curl_multi_close($mh);

?>

我通过调用下面的另一个脚本来测试这个脚本:

<?php 
print microtime();//Return current Unix timestamp with microseconds 
print '<br>';
?>

这是结果,每个句柄的执行时间相差微秒。

0.27085300 1340214659
0.44853600 1340214659
0.46611800 1340214659
0.48201000 1340214659
0.50209400 1340214659
0.48233900 1340214659
0.52274300 1340214659
0.54757800 1340214659
0.57316900 1340214659
0.59475800 1340214659

【讨论】:

  • 你给的路径是什么?如果您提供完整的 URL,localhost/path/to/script.php 它如何知道这是否是同一台服务器。?此外,测试这一点的方法是在 process_a.php 的顶部打印以毫秒为单位的时间,然后您可以检查页面是否一次调用一个。
  • 我认为我的服务器正在检测来自同一用户的多个请求,并且不允许它。就像我在浏览器中加载索引页 5 次一样,它们会一一加载。这就像一个会话? idk D:我会检查以确保不是其他问题...
  • 一个简单的测试是创建一个 time.php 内容: 并使用 curl 多句柄调用此脚本.. 检查不同句柄之间的时间差...
  • @StephenSarcsamKamenar :检查我编辑的答案和测试结果。
  • 有趣。当我从我的 cronjob 中尝试这个,调用我的 process_a.php 文件时,他们一个接一个地执行 1,延迟大约 10 秒。当我像你展示的那样运行一个简单的测试时,它运行良好......我会进行更多测试,并在我有更多关于为什么我的 cronjob 版本不能正常工作的信息时告诉你......
【解决方案2】:

分叉成 10 个进程:

 <?php
 for($i = 0; $i < 10;$i++){
     $pid = pcntl_fork():
     if ($pid == -1) {
          trigger_error('could not fork');
     } else if (!$pid) {
          //we are the child now
           require 'process_a.php';
     } else {
         // we are the parent, you could do something here if need be.
     }
 }

...但是 process_a.php 可以做任何你的网站所做的事情,所以,与其调用一个页面,为什么不做页面请求会导致的实际工作呢?让网络服务器继续成为网络服务器,而不是臃肿的脚本存储库。

【讨论】:

  • pcntl_fork 默认不可用。你觉得值得安装吗?如果我有 7 个不同的文件,我想每次调用 10 次,这会起作用吗?
  • 我正在使用 CURL,因为处理逻辑有时可能在不同的服务器上。
  • 从来没有见过有 cronjobs 的服务器,但没有pcntl_fork 的功能。如果您需要单独安装它,是的,我会说这是值得的。如果你想要 10 x 7 个不同的文件,当然,这也可以(但是,fork 70 次)。
  • 如果你正在准备一个真正的分布式应用程序,我宁愿看GearMan(甚至可以池服务器)然后curl解决方案(但这需要更多的安装)。
  • 默认情况下未启用 PHP 中的安装过程控制支持。在编译 PHP 以启用进程控制支持时,您必须使用 --enable-pcntl 配置选项编译 PHP 的 CGI 或 CLI 版本。注意:目前,此模块无法在非 Unix 平台 (Windows) 上运行。 php.net/manual/en/ref.pcntl.php
【解决方案3】:

你有完整的 cron 可用,还是只能指定 php 文件?

您也许可以使用 xargs 通过 -P 参数分叉 10 个进程

seq `1 10`|xargs -n1 -P10 php /path/to/file.php

【讨论】:

  • 这是什么意思/做什么?你是说我应该放这个而不是调用我的 cronjob.php 吗?我需要运行 cronjob.php 来决定此时应该处理哪些请求。
猜你喜欢
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
相关资源
最近更新 更多