Beknopte handleiding voor de Guava RateLimiter

1. Overzicht

In dit artikel zullen we kijken naar de RateLimiter klasse uit de Guave bibliotheek.

De RateLimiter class is een constructie waarmee we de snelheid waarmee bepaalde bewerkingen plaatsvinden, kunnen regelen. Als we een RateLimiter met N-vergunningen - het betekent dat het proces maximaal N-vergunningen per seconde kan afgeven.

2. Maven Afhankelijkheid

We zullen de bibliotheek van Guava gebruiken:

 com.google.guava guave 29.0-jre 

De laatste versie vind je hier.

3. Maken en gebruiken RateLimiter

Laten we zeggen dat we dat willen beperk de snelheid van uitvoering van de doSomeLimitedOperation () tot 2 keer per seconde.

We kunnen een RateLimiter instantie met behulp van zijn maken () fabrieks methode:

RateLimiter rateLimiter = RateLimiter.create (2);

Vervolgens, om een ​​uitvoeringsvergunning te krijgen van het RateLimiter, we moeten de verkrijgen() methode:

rateLimiter.acquire (1);

Om te controleren of dit werkt, zullen we 2 opeenvolgende oproepen doen naar de gesmoorde methode:

long startTime = ZonedDateTime.now (). getSecond (); rateLimiter.acquire (1); doSomeLimitedOperation (); rateLimiter.acquire (1); doSomeLimitedOperation (); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime;

Laten we dat aannemen om onze tests te vereenvoudigen doSomeLimitedOperation () methode wordt onmiddellijk voltooid.

In dat geval zijn beide aanroepen van de verkrijgen() methode mag niet blokkeren en de verstreken tijd moet minder of minder dan een seconde bedragen - omdat beide vergunningen onmiddellijk kunnen worden verkregen:

assertThat (elapsedTimeSeconds <= 1);

Bovendien kunnen we alle vergunningen in één krijgen verkrijgen() bellen:

@Test openbare leegte gegevenLimitedResource_whenRequestOnce_thenShouldPermitWithoutBlocking () {// gegeven RateLimiter rateLimiter = RateLimiter.create (100); // when long startTime = ZonedDateTime.now (). getSecond (); rateLimiter.acquire (100); doSomeLimitedOperation (); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // dan assertThat (elapsedTimeSeconds <= 1); }

Dit kan handig zijn als we bijvoorbeeld 100 bytes per seconde moeten verzenden. We kunnen honderd keer één byte verzenden om één vergunning tegelijk te verkrijgen. Aan de andere kant kunnen we alle 100 bytes tegelijk verzenden om alle 100 vergunningen in één keer te verkrijgen.

4. Het verkrijgen van vergunningen op een blokkerende manier

Laten we nu een iets ingewikkelder voorbeeld bekijken.

We maken een RateLimiter met 100 vergunningen. Dan voeren we een actie uit waarvoor 1000 vergunningen moeten worden verkregen. Volgens de specificatie van de RateLimiter, een dergelijke actie heeft minstens 10 seconden nodig om te voltooien, omdat we slechts 100 acties per seconde kunnen uitvoeren:

@Test openbare leegte gegevenLimitedResource_whenUseRateLimiter_thenShouldLimitPermits () {// gegeven RateLimiter rateLimiter = RateLimiter.create (100); // when long startTime = ZonedDateTime.now (). getSecond (); IntStream.range (0, 1000) .forEach (i -> {rateLimiter.acquire (); doSomeLimitedOperation ();}); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // dan assertThat (elapsedTimeSeconds> = 10); }

Let op, hoe we de verkrijgen() methode hier - dit is een blokkerende methode en we moeten voorzichtig zijn bij het gebruik ervan. Wanneer de verkrijgen() methode wordt aangeroepen, blokkeert het de uitvoerende thread totdat er een vergunning beschikbaar is.

Bellen met het verkrijgen() zonder argument is hetzelfde als het aanroepen met een als argument - het zal proberen om één vergunning te krijgen.

5. Vergunningen verkrijgen met een time-out

De RateLimiter API heeft ook een erg handig verkrijgen() methode dat accepteert een time-out en TimeUnit als argumenten.

Als u deze methode aanroept wanneer er geen beschikbare vergunningen zijn, zal deze een bepaalde tijd wachten en vervolgens een time-out geven - als er niet genoeg beschikbare vergunningen zijn binnen de time-out.

Als er geen beschikbare vergunningen zijn binnen de gegeven time-out, keert het terug false. Als een verkrijgen() slaagt, het geeft terug waar:

@Test openbare leegte gegevenLimitedResource_whenTryAcquire_shouldNotBlockIndefinitely () {// gegeven RateLimiter rateLimiter = RateLimiter.create (1); // wanneer rateLimiter.acquire (); booleaans resultaat = rateLimiter.tryAcquire (2, 10, TimeUnit.MILLISECONDS); // dan assertThat (resultaat) .isFalse (); }

We hebben een RateLimiter met één vergunning, dus het proberen om twee vergunningen te krijgen zal altijd leiden tryAcquire () terugbrengen false.

6. Conclusie

In deze korte tutorial hebben we de RateLimiter construeren vanuit de Guave bibliotheek.

We hebben geleerd hoe we de RateLimtiter om het aantal vergunningen per seconde te beperken. We zagen hoe we de blokkerende API moesten gebruiken en we gebruikten ook een expliciete time-out om de vergunning te verkrijgen.

Zoals altijd is de implementatie van al deze voorbeelden en codefragmenten te vinden in het GitHub-project - dit is een Maven-project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.


$config[zx-auto] not found$config[zx-overlay] not found