我用Laravel5.2编写了一些代码,从不可靠的API源代码中检索结果。但是,它需要能够在失败的尝试中自动重试请求,因为API调用的结果是503次--大约三分之一次。
我用口香糖来做这件事,我想我知道在处理503个响应之前把代码放在哪里,但是我不知道在那里写什么。
在重试过程中,口吻文档并没有提供太多的内容,我所遇到的所有示例都只展示了如何检索结果(我已经可以这样做),而不是如何让它在需要时重复请求。
我绝不要求任何人为我做这项工作,但我认为我对此的理解已接近极限。如果有人能给我指明正确的方向,我会非常感激的:)
编辑:
我会试着修改。请考虑以下代码。在它中,我想发送一个GET请求,这个请求通常会产生一个JSON响应。
DataController.php
$client = new \GuzzleHttp\Client();
$request = $client->request('GET', 'https://httpbin.org/status/503'); // URI is for testing purposes
当来自这个请求的响应是503时,我可以在这里拦截它:
Handler.php
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)
里面写什么
发布于 2016-02-09 00:46:35
默认情况下,当返回非2**响应时,例外情况抛出。在你的例子中,你看到了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如何处理异常的更多信息,您可以阅读上面的链接。
对于您的情况,让我们在控制器中移动对它自己的方法的gu包调用:
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);
。
发布于 2016-02-09 13:38:19
只是为了增加一些信息,以澄清洛根提出的几点。
在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后,处理程序将按以下顺序执行:
当不提供$handler参数时,GuzzleHttp\HandlerStack::create()
将根据系统上可用的扩展选择最合适的处理程序。如处理程序文档中所示
通过手动创建GuzzleHttp\HandlerStack
,可以将中间件添加到应用程序中。考虑到您最初的问题“如何重复请求”的上下文,我相信您最感兴趣的是在gues6.1中提供的重试中间件。这是一个中间件,它根据提供的决策函数的结果重试请求。
文档还没有赶上这个类。
发布于 2022-09-02 04:23:01
final class HttpClient extends \GuzzleHttp\Client
{
public const SUCCESS_CODE = 200;
private int $attemptsCount = 3;
private function __construct(array $config = [])
{
parent::__construct($config);
}
public static function new(array $config = []): self
{
return new self($config);
}
public function postWithRetry(string $uri, array $options = []): Response
{
$attemptsCount = 0;
$result = null;
do {
$attemptsCount++;
$isEnd = $attemptsCount === $this->attemptsCount;
try {
$result = $this->post(
$uri,
$options,
);
} catch (ClientException $e) {
$result = $e->getResponse();
} catch (GuzzleException $e) {
if ($isEnd) {
Logger::error($e->getMessage());
$result = $e->getResponse();
}
}
} while ($this->isNeedRetry($result, $attemptsCount));
return $result;
}
private function isNeedRetry(?Response $response, int $attemptsCount): bool
{
return $response === null && $attemptsCount < $this->attemptsCount;
}
https://stackoverflow.com/questions/35280647
复制相似问题