请教一下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来看,前面的请求没执行完后面的不会执行,原本就是这么设计的吗?

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 18
goStruct

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

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

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

guzzle 是支持设置代理的

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

试试改用 CurlMultiHandler

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

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

7个月前

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

/**
* 图片上传到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);
    },
]);
7个月前

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

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

不会堵塞。

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

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

7个月前

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);
}
7个月前
    yield new Request('GET', $uri);  要改为 getAsync
7个月前 评论
renji566 (楼主) 7个月前

file

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

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