hyperf/docs/zh-hk/guzzle.md

125 lines
3.3 KiB
Markdown
Raw Normal View History

2019-03-31 22:48:29 +08:00
# Guzzle HTTP 客户端
2019-12-12 16:24:04 +08:00
[hyperf/guzzle](https://github.com/hyperf/guzzle) 組件基於 Guzzle 進行協程處理,通過 Swoole HTTP 客户端作為協程驅動替換到 Guzzle 內,以達到 HTTP 客户端的協程化。
2019-03-31 22:48:29 +08:00
2019-12-12 16:24:04 +08:00
## 安裝
2019-03-31 22:48:29 +08:00
```bash
composer require hyperf/guzzle
```
## 使用
2019-12-12 16:24:04 +08:00
只需要該組件內的 `Hyperf\Guzzle\CoroutineHandler` 作為處理器設置到 Guzzle 客户端內即可轉為協程化運行,為了方便創建協程的 Guzzle 對象,我們提供了一個工廠類 `Hyperf\Guzzle\ClientFactory` 來便捷的創建客户端,代碼示例如下:
2019-03-31 22:48:29 +08:00
```php
2019-05-06 15:18:45 +08:00
<?php
use Hyperf\Guzzle\ClientFactory;
class Foo {
/**
* @var \Hyperf\Guzzle\ClientFactory
*/
private $clientFactory;
public function __construct(ClientFactory $clientFactory)
{
$this->clientFactory = $clientFactory;
}
public function bar()
{
2019-12-12 16:24:04 +08:00
// $options 等同於 GuzzleHttp\Client 構造函數的 $config 參數
2019-05-06 15:18:45 +08:00
$options = [];
2019-12-12 16:24:04 +08:00
// $client 為協程化的 GuzzleHttp\Client 對象
2019-05-06 15:18:45 +08:00
$client = $this->clientFactory->create($options);
}
}
2019-06-06 14:08:47 +08:00
```
2019-11-12 19:46:54 +08:00
## 使用 Swoole 配置
2019-07-12 09:42:34 +08:00
2019-12-12 16:24:04 +08:00
有時候我們想直接修改 `Swoole` 配置,所以我們也提供了相關配置項,不過這項配置在 `Curl Guzzle 客户端` 中是無法生效的,所以謹慎使用。
2019-07-12 09:42:34 +08:00
2019-12-12 16:24:04 +08:00
> 這項配置會替換原來的配置,比如以下 timeout 會被 10 替換。
2019-07-12 09:42:34 +08:00
```php
<?php
use GuzzleHttp\Client;
use Hyperf\Guzzle\CoroutineHandler;
use GuzzleHttp\HandlerStack;
$client = new Client([
'base_uri' => 'http://127.0.0.1:8080',
'handler' => HandlerStack::create(new CoroutineHandler()),
'timeout' => 5,
'swoole' => [
'timeout' => 10,
'socket_buffer_size' => 1024 * 1024 * 2,
],
]);
$response = $client->get('/');
```
2019-12-12 16:24:04 +08:00
## 連接池
2019-06-06 14:08:47 +08:00
2019-12-12 16:24:04 +08:00
Hyperf 除了實現了 `Hyperf\Guzzle\CoroutineHandler` 外,還基於 `Hyperf\Pool\SimplePool` 實現了 `Hyperf\Guzzle\PoolHandler`
2019-06-06 14:08:47 +08:00
### 原因
2019-12-12 16:24:04 +08:00
簡單來説,主機 TCP 連接數 是有上限的當我們併發大到超過這個上限值時就導致請求無法正常建立。另外TCP 連接結束後還會有一個 TIME-WAIT 階段,所以也無法實時釋放連接。這就導致了實際併發可能遠低於 TCP 上限值。所以,我們需要一個連接池來維持這個階段,儘量減少 TIME-WAIT 造成的影響,讓 TCP 連接進行復用。
2019-06-06 14:08:47 +08:00
### 使用
```php
<?php
2019-06-06 14:08:47 +08:00
use GuzzleHttp\Client;
use Hyperf\Utils\Coroutine;
use GuzzleHttp\HandlerStack;
use Hyperf\Guzzle\PoolHandler;
use Hyperf\Guzzle\RetryMiddleware;
2019-07-29 16:45:28 +08:00
$handler = null;
if (Coroutine::inCoroutine()) {
$handler = make(PoolHandler::class, [
'option' => [
'max_connections' => 50,
],
2019-06-06 14:08:47 +08:00
]);
2019-07-29 16:45:28 +08:00
}
2019-06-06 14:08:47 +08:00
2019-12-12 16:24:04 +08:00
// 默認的重試Middleware
2019-07-29 16:45:28 +08:00
$retry = make(RetryMiddleware::class, [
'retries' => 1,
'delay' => 10,
]);
2019-06-06 14:08:47 +08:00
2019-07-29 16:45:28 +08:00
$stack = HandlerStack::create($handler);
$stack->push($retry->getMiddleware(), 'retry');
2019-06-06 14:08:47 +08:00
$client = make(Client::class, [
'config' => [
2019-07-29 16:45:28 +08:00
'handler' => $stack,
2019-06-06 14:08:47 +08:00
],
]);
2019-10-16 14:13:13 +08:00
```
2019-12-12 16:24:04 +08:00
另外,框架還提供了 `HandlerStackFactory` 來方便創建上述的 `$stack`
2019-10-16 14:13:13 +08:00
```php
<?php
use Hyperf\Guzzle\HandlerStackFactory;
use GuzzleHttp\Client;
$factory = new HandlerStackFactory();
$stack = $factory->create();
$client = make(Client::class, [
'config' => [
'handler' => $stack,
],
]);
```