Php 如何让Guzzle 6在Laravel中出现503错误时重试请求

Php 如何让Guzzle 6在Laravel中出现503错误时重试请求,php,http,middleware,guzzle6,Php,Http,Middleware,Guzzle6,我在Laravel5.2中编写了一些代码,用于从不可擦除的API源检索结果。但是,它需要能够在尝试失败时自动重试请求,因为API调用大约三分之一的时间会导致503 我正在使用Guzzle来做这件事,我想我知道在处理503个响应之前,应该把截获它们的代码放在哪里;但我不知道该写些什么 guzzle文档并没有提供太多关于重试的内容,我在guzzle 6中遇到的所有示例都只显示了如何检索结果(我已经可以这样做了),而没有显示如何让它在需要时重复请求 我决不是要求任何人为我做这项工作,但我认为我在这方面

我在Laravel5.2中编写了一些代码,用于从不可擦除的API源检索结果。但是,它需要能够在尝试失败时自动重试请求,因为API调用大约三分之一的时间会导致503

我正在使用Guzzle来做这件事,我想我知道在处理503个响应之前,应该把截获它们的代码放在哪里;但我不知道该写些什么

guzzle文档并没有提供太多关于重试的内容,我在guzzle 6中遇到的所有示例都只显示了如何检索结果(我已经可以这样做了),而没有显示如何让它在需要时重复请求

我决不是要求任何人为我做这项工作,但我认为我在这方面的理解已经接近极限。如果有人能给我指出正确的方向,我将不胜感激:)

编辑:

我会努力复习的。请考虑以下代码。在其中,我想发送一个GET请求,该请求通常会产生一个JSON响应

DataController.php

$client = new \GuzzleHttp\Client();
$request = $client->request('GET', 'https://httpbin.org/status/503'); // URI is for testing purposes
public function render($request, Exception $e)
{
  if ($e->getCode() == 503)
  {
    // Code that would tell Guzzle to retry the request 5 times with a 10s delay before failing completely
  }

  return parent::render($request, $e);
}
当此请求的响应为503时,我可以在此处拦截它:

Handler.php

$client = new \GuzzleHttp\Client();
$request = $client->request('GET', 'https://httpbin.org/status/503'); // URI is for testing purposes
public function render($request, Exception $e)
{
  if ($e->getCode() == 503)
  {
    // Code that would tell Guzzle to retry the request 5 times with a 10s delay before failing completely
  }

  return parent::render($request, $e);
}
我不知道这是最好的地方,但真正的问题是我不知道在
if($e->getCode()==503)

当返回非2**响应时,默认情况下Guzzle会抛出什么。在你的例子中,你看到的是503响应。异常可以被认为是应用程序可以从中恢复的错误。其工作方式是使用
try-catch

try {
    // The code that can throw an exception will go here
    throw new \Exception('A generic error');
    // code from here down won't be executed, because the exception was thrown.
} catch (\Exception $e) {
    // Handle the exception in the best manner possible.
}
在块的
try
部分包装可能引发异常的代码。然后在块的
catch
部分添加错误处理代码。有关php如何处理异常的更多信息,请阅读上面的链接

对于您的情况,让我们将Guzzle调用移动到控制器中它自己的方法:

public function performLookUp($retryOnError = false)
{
    try {
        $client = new \GuzzleHttp\Client();
        $request = $client->request('GET', 'https://httpbin.org/status/503'); 
        return $request->send();
    } catch (\GuzzleHttp\Exception\BadResponseException $e) {
        if ($retryOnError) {
            return $this->performLookUp();
        }
        abort(503);
   }
}

现在,您可以在控制器中执行,
$this->performLookUp(true)

我只是想补充一些信息来澄清洛根提出的几点

Guzzle“可以”对2**/3**以外的响应抛出异常。这完全取决于如何创建
GuzzleHttp\HandlerStack

$stack = GuzzleHttp\HandlerStack::create();
$client = new Client(['handler'=> $stack]);

$client = new Client();
// These two methods of generating a client are functionally the same.


$stack = New GuzzleHttp\HandlerStack(new GuzzleHttp\Handler\CurlHandler());
$client = new Client(['handler'=> $stack]);
// This client will not throw exceptions, or perform any of the functions mentioned below.
create方法将默认处理程序添加到HandlerStack。解析HandlerStack后,处理程序将按以下顺序执行:

  • 发送请求:
  • http_错误-发送请求时无操作。在堆栈上返回响应承诺时,将在响应处理中检查响应状态代码
  • 允许重定向-发送请求时无操作。在堆栈上返回响应承诺时,会发生以下重定向
  • cookies-将cookies添加到请求中
  • prepare_body-将准备HTTP请求的主体(例如,添加默认头,如内容长度、内容类型等)
  • 使用处理程序发送请求
  • 处理响应:
  • 准备_body-响应处理无操作
  • cookies-将响应cookies提取到cookie罐中
  • 允许重定向-遵循重定向。 4.http_错误-当响应状态代码>=300时引发异常
  • 如果未提供$handler参数,
    GuzzleHttp\HandlerStack::create()
    将根据系统上可用的扩展选择最合适的处理程序。如合同中所示

    通过手动创建
    GuzzleHttp\HandlerStack
    ,可以将中间件添加到应用程序中。鉴于您最初提出的问题“我如何重复该请求”,我相信您对Guzzle 6.1中提供的内容最感兴趣。这是一个中间件,它根据提供的决策函数的结果重试请求


    文档还没有赶上这门课。

    大家好,欢迎来到SO。请阅读并提出一个更受欢迎的问题。嗨,达维加尔,部分问题是,我不确定该写什么,但我已经尝试更好地说明这个问题。如果这仍然没有帮助,让我知道,我会再试一次。谢谢,谢谢你的回复。不幸的是,我不得不在没有这个函数的情况下打开我所拥有的,但我将尝试在下一个可用的机会完成它(为了知识)。所以我会尝试一下,让你知道它是怎么回事。再次感谢。