2013-05-20 138 views
3

我试图通过API运行一个大量的字段值更新,我跑到我的PHP脚本的最大执行时间。异步PHP执行

我分了我的作业分成较小的任务异步运行他们的小作业......

Asynchronous PHP calls?

我发现这个职位,它看起来约权,但评论都有点倒胃口.. 。使用curl来运行外部脚本文件会阻止调用者文件触发最大执行时间,或者curl是否仍然等待来自服务器的响应并终止我的页面?

问题的确是:你如何在PHP中执行异步作业?像Ajax一样。

编辑:: ///

有一个拥有大量的数据行的项目管理工具。 我正在使用此工具API访问数据行并将其显示在我的页面上。 使用我的工具的用户将使用复选框选择多行数据,并在框中键入新值。 然后用户将按下“更新行值”按钮,该按钮将运行更新脚本。

此更新脚本分项目的数百或数千可能选入的100

组在这一点上我会使用一些异步方法接触项目管理工具和更新所有100个项目。

因为当它更新这些项目时,它可能需要很长时间来运行其进程,我需要确保我的原始页面拆分这些作业不再等待来自该操作的请求,以便我可以引发更多更新项目的请求。并允许我的服务器页面对我的用户说:“好吧,更新正在发生,可能需要一段时间,我们会在完成后发送电子邮件。”

$step = 100; 
    $itemCount = GetItemCountByAppId($appId); 
    $loopsRequired = $itemCount/$step;    
    $loopsRequired = ceil($loopsRequired); 

    $process = array(); 

    for($a = 0; $a < $loopsRequired; $a++) 
    { 
     $items = GetItemsByAppId($appId, array( 
      "amount" => $step, 
      "offset" => ($step * $a) 
     )); 

     foreach($items[ "items" ] as $key => $item) 
     { 
      foreach($fieldsGroup as $fieldId => $fieldValues) 
      { 
       $itemId = $item->__attributes[ "item_id" ]; 
       /*array_push($process, array(
        "itemId" => $itemId, 
        "fieldId" => $fieldId, 
       ));*/ 
       UpdateFieldValue($itemId, $fieldId, $fieldValues); 
       // This Update function is actually calling the server and I assume it must be waiting for a response... thus my code times out after 30 secs of execution 
      } 
     } 

     //curl_post_async($url, $params); 
    } 
+3

使用队列/工作系统! AMQP,ZeroMQ,Gearman等是你的朋友。 – deceze

+1

通过命令行启动它们为您提供了一个可行的选项? –

+0

这是需要自动化并且长度可变的东西。有些工作可能最终每次只需要5分钟的时间......如果我可以将工作分成较小的数量并完成异步工作,那么一旦操作完成,我就可以简单地向用户发送电子邮件......所以,说实话...我不完全确定这是一个可行的解决方案 – Jimmyt1988

回答

0

如果您使用的是PHP-CLI,尝试Threads,或fork()非线程安全版本。

+0

如果我在新线程中关闭少量工作,这会停止最大执行吗? – Jimmyt1988

+2

它不会。您需要set_time_limit(0)以便脚本可以无限期地继续。然而,这背后有一个完整的机制,你如何传递消息,如何构建回复等,只是使用线程或分支进程将不会有太大的帮助。你应该研究像deceze说的工作队列,否则你最终会自己创建(使用线程或分叉进程)。 –

+0

感谢一大堆..大的帮助。 – Jimmyt1988

1

根据您的实现方式,异步PHP可能用于将Web请求从处理中分离出来,从而将Web请求与处理中的任何超时隔离(但您可以在单个线程中执行相同的操作)。将任务分解为更小的并发部分会使其运行速度更快吗?可能不会 - 通常这会延长完成作业的时间长度 - 关于唯一不是这种情况的时间是,当您拥有非常大的处理能力并且可以有效地分配任务时(例如,map-reduce )。 HTTP调用(curl)是一种有效的方式来分发这样的工作吗?没有。还有其他的方法,包括同步和异步消息传递,批处理,进程分叉,线程......各有其优点和复杂性 - 我们不知道你想要解决的问题是什么。

所以即使在我们遇到您的具体问题之前,这看起来并不是一个好策略。

将使用curl运行外部脚本文件防止来电文件触发

它会在目标服务器上配置任何超时被限制最长执行时间 - 如果这是在同一台服务器调用脚本,那么它将是相同的超时。

curl是否仍然等待来自服务器的响应并终止我的页面?

我不知道你在问什么 - 这意味着你有没有告诉我们有关于功能的依赖关系。

这听起来像你选择了一个解决方案,现在正在努力使它适合你的问题。

+0

我已将上下文添加到我的帖子中。感谢您的时间 – Jimmyt1988

+0

您的瓶颈很可能是数据库 - 将工作分解为并行运行并不会让它变得更快。在Web服务器之外调用繁重的列表将避免超时问题(http://symcbean.blogspot.co.uk/2010/02/php-and-long-running-processes.html),但有更好的方法 - 例如在用户与其交互时尽快更新每行,限制UI,以便它们一次不能更新超过100行(并复用查询)。 – symcbean