40秒后随机获得504网关超时

时间:2015-10-26 10:23:25

标签: php laravel timeout guzzle gateway

我的服务器正在运行Apache,FPM / FastCGI和PHP 5.5.30。

我有Laravel 5.0框架和Guzzle来管理不同类型的HTTP请求。

在Guzzle之前我使用Rolling-Curl在paraller中发出请求。我之所以将Rolling-Curl改为Guzzle的原因是我随机获得了504个网关错误,但经过几次测试后我注意到我甚至用Guzzle得到了它。

网关错误总是在40秒后发生并且随机发生。如果我多次击中F5(刷新)它会消失,但可能会再次发生。

以下是我的代码段     

$feeds = Feeds::where('active', '=', '1')->lists('url');  

$client = new \GuzzleHttp\Client();

$requests = array();

foreach($feeds AS $feed)
{
  $requests[] = $client->createRequest('GET', $feed);
}

$pool = new Pool($client, $requests, [
  'pool_size' => '5',
  'timeout' => '120',
  'connect_timeout' => '120',
  'complete' => function (CompleteEvent $event) {
    echo 'Completed request to ' . $event->getRequest()->getUrl() . " - ". $event->getResponse()->getStatusCode() . "\n";
    //echo 'Response: ' . $event->getResponse()->getBody() . "\n\n";
  },       
  'error' => function (ErrorEvent $event) {
      echo 'Request failed: ' . $event->getRequest()->getUrl() . "\n";
      echo $event->getException();
  }
]);


$pool->wait();

echo "...done in " . (microtime(true) - $start);
?>

$feeds从数据库获取100个RSS URL,我的池一次获得最多5个Feed的内容。

1 个答案:

答案 0 :(得分:0)

您是否可以发布您获得的确切错误,并可能确定代码行,指出抛出异常的位置?我认为您可以单独或组合使用两件事来解决错误:

  • 在您的池启动选项中添加'rejected'功能以处理失败的请求,请参阅Guzzle documentation
  • 如果仅try {} catch {} block选项没有修复错误,请将代码行包裹在'rejected' function


    请参阅下面修改的代码以包含我的建议:

    $feeds = Feeds::where('active', '=', '1')->lists('url');  
    
    $client = new \GuzzleHttp\Client();
    
    $requests = array();
    
    foreach($feeds AS $feed)
    {
        $requests[] = $client->createRequest('GET', $feed);
    }
    
    $pool = new Pool($client, $requests, [
      'pool_size' => '5',
      'timeout' => '120',
      'connect_timeout' => '120',
      'complete' => function (CompleteEvent $event) {
        echo 'Completed request to ' . $event->getRequest()->getUrl() . " - ". $event->getResponse()->getStatusCode() . "\n";
        //echo 'Response: ' . $event->getResponse()->getBody() . "\n\n";
      },       
      'error' => function (ErrorEvent $event) {
          echo 'Request failed: ' . $event->getRequest()->getUrl() . "\n";
          echo $event->getException();
       },
       //add the 'rejected' function
       'rejected' => function ($reason, $index) {
           //handle failed requests here
       },
    ]);
    
    //throw in the try{} catch {} block if the 'rejected' function is not fixing the 504 error
    try {
        //your code goes here...I suspect it's the $pool->wait()
        $promise = $pool->promise(); //I included this line from the Guzzle documentation
        $promise->wait();
    } catch (ServerException $e) {
        //Catch exception for 504 error here; you probabbly want to retry recursively a number of times before giving up...
    }
    
    echo "...done in " . (microtime(true) - $start);