本文介绍了什么是确切的“并发”?在食尸鬼?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Pool 中找不到关于并发选项的太多信息。

I have not found much information about concurrency option in Pool.

如果这是可以在服务器上打开的多个TCP套接字,那么问题是我可以使用多少个并发来更快地处理请求?。

If this is a number of TCP sockets which could be opened on server, then the question is "What number of concurrency could I use in order to handle requests quicker?".

我有使用游泳池的示例:

    // I am using Laravel, this is basically retrieving entities from DB
    $exchangers = Exchanger::all();

    $client = new Guzzlelient();

    $requests = [];
    foreach ($exchangers as $exchanger)
    {
        $requests[$exchanger->id] = new Request('GET', $exchanger->xml_feed_url);
    }

    $pool = new Pool($client, $requests, [
        'concurrency' => 5,
        'options' => [
            'verify' => false
        ],
        'fulfilled' => function ($response, $index) {
            echo "fulfilled: " . $index."\n";
        },
        'rejected' => function ($reason, $index) {
            echo "rejected: " . $index. "\n";
        },
    ]);

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

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

在大约20个站点上并发设置为5,花费了大约10秒钟。现在我在想,好吧,这是套接字的数量。套接字〜端口。我有65535个端口。很酷,为什么不将并发设置为50,我应该在一秒钟左右的时间内得到所有结果?。很好,我将其设置为50,并且...花了8秒。但是一个小时前的结果是18秒vs 24(50个并发,所以它甚至更慢)。

It took about 10 seconds to go over ~20 sites with concurrency set to 5.Now I'm thinking like, "Okay, this is number of sockets. Sockets ~ Ports. I have 65535 ports. Cool, why not set concurrency 50 and I should get all results in a second or so?". Nice, I set it to 50 and... it took 8 seconds. However an hour ago the results were like 18 seconds vs 24 (for 50 concurrency, so it's even slower).

所以问题是:


  1. 如何确定我可以使用哪种并发来优化流程并使其尽可能快地完成?

  2. 无论如何,并发是什么?


推荐答案

这就是您所期望的。您发送X个并发请求,但仅同时发送并发请求。每当请求完成时,就会将另一个请求排队()

It's what you'd expect it to be. You send X concurrent requests but only concurrency requests are sent at the same time. Whenever a request finishes then another one is queued (source code)

在源代码中是这样的:

private function refillPending()
{
    if (!$this->concurrency) {
        // Add all pending promises.
        while ($this->addPending() && $this->advanceIterator());
        return;
    }
    // Add only up to N pending promises.
    $concurrency = is_callable($this->concurrency)
        ? call_user_func($this->concurrency, count($this->pending))
        : $this->concurrency;
    $concurrency = max($concurrency - count($this->pending), 0);
    // Concurrency may be set to 0 to disallow new promises.
    if (!$concurrency) {
        return;
    }
    // Add the first pending promise.
    $this->addPending();
    // Note this is special handling for concurrency=1 so that we do
    // not advance the iterator after adding the first promise. This
    // helps work around issues with generators that might not have the
    // next value to yield until promise callbacks are called.
    while (--$concurrency
        && $this->advanceIterator()
        && $this->addPending());
}

每次请求完成时都会调用此方法(函数步骤设置为在每次失败回调成功后调用。

This method is called every time a request finishes (function step is set to be called after every success of failiure callback).

但是,总的来说,更多并不总是意味着更好,因为您可能会遇到其他限制,例如OS套接字或ISP速率限制或远程服务器速率限制(如果所有请求都通过)到同一台服务器)。在大多数情况下,最佳值是通过反复试验得出的。

However as a general rule more does not always mean better because you might hit other limits elsewhere like OS sockets or ISP rate limiting or remote server rate limiting (if all requests go to the same server). In most cases the optimal value is found via trial and error.

这篇关于什么是确切的“并发”?在食尸鬼?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 04:52