请教一下guzzle的pool问题

use GuzzleHttp\Pool;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;


$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());

$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
    Log::write(':请求的数据:' . $request->getBody());
    return $request;
}));

$client = new Client(['handler' => $stack]);


$requests = function ($total) {
    $uri = 'https://www.google.com';
    for ($i = 0; $i < $total; $i++) {
        yield new Request('GET', $uri);
    }
};

$pool = new Pool($client, $requests(100), [
    'concurrency' => 5,
    'fulfilled' => function ($response, $index) {
        // this is delivered each successful response
    },
    'rejected' => function ($reason, $index) {
        // this is delivered each failed request
    },
]);

// Initiate the transfers and create a promise
$promise = $pool->promise();

// Force the pool of requests to complete.
$promise->wait();

发现一个问题,这个pool并发如果前面的一个阻塞了还没有收到响应,后面的请求并不会被请求出去,我用中间件记录了请求的body来看,前面的请求没执行完后面的不会执行,原本就是这么设计的吗?

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 18
goStruct

用异步请求方法比如getAsync之类的

6个月前 评论
renji566 (楼主) 6个月前

使用 fiddler 抓包看下请求内容吧 看看是卡在哪个步骤了

guzzle 是支持设置代理的

6个月前 评论
renji566 (楼主) 6个月前
kis龍 (作者) 6个月前

试试改用 CurlMultiHandler

6个月前 评论
renji566 (楼主) 6个月前

准备多点地址试试,如果都是 google,估计 dns,connect 都过不了 方便提供贴一下运行输出的内容吗

6个月前

你应该看起来好像写的不对哇。给你看看我写的:

/**
* 图片上传到OSS逻辑
*/
$client = new Client(['base_uri' => 'https://' . $this->full_endpoint]);

// 创建 HTTP 请求
$request = function ($images) use ($client) {
    /**
        * @var string $key   文件名
        * @var Stream $image 图片流
        */
    foreach ($images as $key => $image) {
        if ($image['stream'] === null) { // 如果进入此分支,说明之前的下载出现了问题
            continue;
        }

        yield $key => function () use ($client, $image) {
            // 创建请求
            $request = new Request('PUT', $image['generate'], [
                'Host'           => $this->full_endpoint,
                'Content-Type'   => self::MIME_TYPES[$image['ext']],
                'Content-Length' => $image['stream']->getSize(),
                'Date'           => gmdate('D, d M Y H:i:s \G\M\T'),
            ], $image['stream']);

            return $client->sendAsync($this->sign($request, [
                'bucket' => $this->bucket,
                'key'    => $request->getUri()->getPath(),
            ]));
        };
    }
};

// 设置管道
$pool = new Pool($client, $request($imagesMap), [
    'concurrency' => $this->concurrency,
    'rejected'    => function (RequestException $reason, $index) use ($imagesMap) { // 这里是失败处理逻辑
        Log::warning('图片上传失败', [$imagesMap[$index]['original'], $imagesMap[$index]['generate']]);
        dispatch(new XsSaveOssJob($imagesMap[$index]['original'], $imagesMap[$index]['generate']))->delay(5);
    },
]);
6个月前

pool 相当于把很多请求放在一个array 循环请求,然后看起来是需要之前的请求完成后才会执行后面的请求。
该说不是你想要那种全部请求同时执行
guzzle 的话有专门的方法来做同时请求

6个月前 评论
renji566 (楼主) 6个月前
deatil (作者) 6个月前

不会堵塞。

guzzle 没试过, 我之前用laravel - 并发请求 没问题的。

估计是你代码问题,可以用 laravel 文档的测试。

6个月前

CurlMultiHandler支持Guzzle的, 另外题主试试加参timeout

$curlMultiHandler = new CurlMultiHandler();
$client           = new Client(['handler' => $curlMultiHandler]);

for ($i = 0; $i < 100; $i++) {

    $client->getAsync('https://www.qq.com/')
    ->then(function (Response $response) {
        var_dump($response->getStatusCode());
    });

}


while (1) {
    $curlMultiHandler->tick();
    usleep(100000);
}
6个月前
    yield new Request('GET', $uri);  要改为 getAsync
6个月前 评论
renji566 (楼主) 6个月前

file

6个月前 评论
把代码写成诗 (作者) 6个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!