Guzzle是一個PHP的HTTP客戶端,可以發送同步或異步的請求,中間件系統允許你創建構成客戶端行爲。
在網絡不穩定或者其他一些原因導致會偶現請求失敗的情況,所以就需要根據一定規則進行請求重試
而本文中請求重試就是利用中間件系統實現的。
使用php的trait特性
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\Middleware;
trait TraitGuzzleRetry
{
/**
* @var int 最大重試次數
*/
private $maxRetries = 3;
/**
* @var Client
*/
private $client;
/**
* 功 能:設置最大重試次數
* 修改日期:2020/4/20
*
* @param int $maxRetries 最大重試次數
* @return $this
*/
public function setMaxRetries(int $maxRetries)
{
$this->maxRetries = $maxRetries;
return $this;
}
/**
* 功 能:獲取最大重試次數
* 修改日期:2020/4/20
*
* @return int
*/
public function getMaxRetries()
{
return $this->maxRetries;
}
/**
* 功 能:返回一個匿名函數, 匿名函數若返回false 表示不重試,反之則表示繼續重試
* 修改日期:2020/4/20
*
* @return Closure
*/
protected function retryDecider()
{
return function ($retries, Request $request, Response $response = null, RequestException $exception = null) {
if ($retries > $this->getMaxRetries()) {
return false;
}
if (!is_null($exception)) {
return true;
}
if ($response && $response->getStatusCode() >= 500) {
return true;
}
return false;
};
}
/**
* 功 能:返回一個匿名函數,該匿名函數返回重試延遲時間(毫秒),guzzle會在此返回值基礎上加10 s
* 修改日期:2020/4/20
*
* @return Closure
*/
protected function retryDelay()
{
return function ($numberOfRetries) {
return 1000 * $numberOfRetries;
};
}
/**
* 功 能:獲取guzzle client
* 修改日期:2020/4/20
*
* @param array $config 配置
* @param bool $share 單例模式
* @return Client
*/
public function getClient(array $config = [], $share = true)
{
if ($share && !empty($this->client)) {
return $this->client;
}
$handlerStack = HandlerStack::create(new CurlHandler());
$handlerStack->push(Middleware::retry($this->retryDecider(), $this->retryDelay()));
$client = new Client(array_merge(['handler' => $handlerStack], $config));
$share && $this->client = $share;
return $client;
}
}
其中retryDecider
方法是判斷是否重試,retryDelay
方法是獲取下次重試間隔時間,可以根據具體業務進行重寫