4

外部サーバーへの送信 PHP+curl リクエストを (遅延して) レート制限して、1 秒あたり n リクエストのみにする方法はありますか? PHP は Fastcgi モードで使用されるため、スリープは使用できません。

4

2 に答える 2

1

はい。curl マルチハンドラーがあります...

(このライブラリを使用してOOP方式で行うことができます)

例えば:

    // Creates the curl multi handle
    $mh = curl_multi_init();
    $handles = array();

    foreach($urls as $url)
    {
        // Create a new single curl handle
        $ch = curl_init();

        // Set options
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 300);

        // Add to the multi handle
        curl_multi_add_handle($mh,$ch);

        // Put the handles in an array to loop this later on
        $handles[] = $ch;
    }

    // Execute the multi handle
    $running=null;

    do
    {
        $mrc = curl_multi_exec($mh,$running);

        // Added a usleep for 0.50 seconds to reduce load
        usleep (250000);
    }
    while($running > 0);

    // Get the content of the urls (if there is any)
    $output = array();
    for($i=0; $i<count($handles); $i++)
    {
        // Get the content of the handle
        $content = curl_multi_getcontent($handles[$i]);
        $output[] = $content;

        if($printOutput) {
            echo $content;
        }

        // Remove the handle from the multi handle
        curl_multi_remove_handle($mh,$handles[$i]);
    }

    // close the multi curl handle to free system resources
    curl_multi_close($mh);
于 2012-09-10T19:48:41.420 に答える
1

トークン バケット アルゴリズムを使用してレートを制御できます。1 つのリソースに対するすべての PHP プロセスの速度を制御したい場合は、バケットの状態を共有する必要があります。私の実装ではスレッドセーフな方法でこれを行うことができます: bandwidth-throttle/token-bucket

use bandwidthThrottle\tokenBucket\Rate;
use bandwidthThrottle\tokenBucket\TokenBucket;
use bandwidthThrottle\tokenBucket\BlockingConsumer;
use bandwidthThrottle\tokenBucket\storage\FileStorage;

$storage  = new FileStorage(__DIR__ . "/api.bucket");
$rate     = new Rate(10, Rate::SECOND);
$bucket   = new TokenBucket(10, $rate, $storage);
$consumer = new BlockingConsumer($bucket);
$bucket->bootstrap(10);

// This blocks all processes to the rate of 10 requests/second
$consumer->consume(1);

$api->doSomething();
于 2015-07-12T18:42:10.637 に答える