2016-05-03 12 views
1

Ich verwende https://github.com/bandwidth-throttle/token-bucket für Abfragen, die auf den externen Server beschränkt sind. Mein Code:Verzögerung in Bandbreite-Drossel/Token-Bucket (PHP)

function main() { 
    unlink(__DIR__ . "/api.bucket2"); 
    $storage = new FileStorage(__DIR__ . "/api.bucket2"); 
    $rate  = new Rate(3, Rate::SECOND); 
    $bucket = new TokenBucket(3, $rate, $storage); 
    $bucket->bootstrap(3); 
    $consumer = new BlockingConsumer($bucket); 

    for ($i = 0; $i < 12; $i++) { 
     $consumer->consume(1); 

     work(); 
    } 
} 

function work() { 
    echo date("d.m.Y H:i:s") . substr((string)microtime(), 1, 4) . "\n"; 
} 

main(); 

Ergebnis:

-bash-4.2$ php -f worker-test.php 
03.05.2016 14:26:16.785 
03.05.2016 14:26:16.785 
03.05.2016 14:26:16.786 
03.05.2016 14:26:17.118 
03.05.2016 14:26:17.451 
03.05.2016 14:26:17.784 
... 

ich erwartet, dass die Funktion wird 3-mal pro Sekunde aufgerufen werden, aber es ist nicht. Die ersten 6 Anrufe erfolgten in 1 Sekunde. wenn ich "Eimer-$> Bootstrap (3);" ändern auf "$ Eimer-> Bootstrap (0);", wird es besser sein:

03.05.2016 14:33:34.913 
03.05.2016 14:33:35.245 
03.05.2016 14:33:35.578 
03.05.2016 14:33:35.911 
... 

aber es ist noch mehr als 3 pro Sekunde. Was mache ich falsch?

Antwort

2
$bucket->bootstrap(3); 

TokenBucket::bootstrap(3) legt drei Anfangs Token in den Eimer. Diese anfänglichen Tokens können sofort verbraucht werden. Sie drosseln effektiv nicht die Rate für diese ersten Anrufe.

Wenn Sie diesen ersten Burst nicht möchten, haben Sie den Bootstrapping ohne Token korrekt durchgeführt.

03.05.2016 14:33:34.913 
03.05.2016 14:33:35.245 
03.05.2016 14:33:35.578 
03.05.2016 14:33:35.911 

aber es ist noch mehr als 3 pro Sekunde.

Ich zähle 3 pro Sekunde. Bitte tolerieren Sie diese beobachtete Abweichung von ± 1 ms. Auf die Dauer wirst du durchschnittlich 3 pro Sekunde bekommen.

Dieser ± 1ms wahrscheinlich aus this implementation detail von BlockingConsumer kommt:

// sleep at least 1 millisecond. 
usleep(max(1000, $seconds * 1000000)); 
+0

habe ich noch ein paar Tests und stellte fest, dass, wenn die Datei oder Schlüssel (Speicher) existiert bisher nicht, so fein ist alles. Aber wenn sie erschaffen wurden, ist etwas seltsam. Der rote Balken ist schnell Token, Blau - Token pro Sekunde, es ist falsch. [Bild] (http://i.imgur.com/olV7yIZ.png). Vielleicht verstehe ich etwas falsch? – dmr