Hurtigguide til Guava RateLimiter

1. Oversikt

I denne artikkelen ser vi på RateLimiter klasse fra Guava bibliotek.

De RateLimiter klasse er en konstruksjon som lar oss regulere hastigheten som noen behandling skjer med. Hvis vi lager en RateLimiter med N-tillatelser - det betyr at prosessen maksimalt kan utstede N-tillatelser per sekund.

2. Maven avhengighet

Vi bruker Guavas bibliotek:

 com.google.guava guava 29.0-jre 

Den siste versjonen finner du her.

3. Opprette og bruke RateLimiter

La oss si at vi vil begrense gjennomføringsgraden av doSomeLimitedOperation () til 2 ganger per sekund.

Vi kan lage en RateLimiter eksempel bruker sin skape() fabrikk metode:

RateLimiter rateLimiter = RateLimiter.create (2);

Neste, for å få en gjennomføringstillatelse fra RateLimiter, vi må ringe tilegne() metode:

rateLimiter.acquire (1);

For å sjekke at det fungerer, ringer vi to påfølgende samtaler til strupemetoden:

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

For å forenkle testingen, la oss anta det doSomeLimitedOperation () metoden fullføres umiddelbart.

I slike tilfeller begge påkallinger av tilegne() metoden skal ikke blokkere og den forløpne tiden skal være kortere eller under ett sekund - fordi begge tillatelsene kan anskaffes umiddelbart:

assertThat (elapsedTimeSeconds <= 1);

I tillegg kan vi anskaffe alle tillatelser i ett tilegne() anrop:

@Test offentlig ugyldighet givenLimitedResource_whenRequestOnce_thenShouldPermitWithoutBlocking () {// gitt RateLimiter rateLimiter = RateLimiter.create (100); // når lang starttid = ZonedDateTime.now (). getSecond (); rateLimiter.acquire (100); doSomeLimitedOperation (); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // deretter assertThat (elapsedTimeSeconds <= 1); }

Dette kan være nyttig hvis vi for eksempel trenger å sende 100 byte per sekund. Vi kan sende hundre ganger en byte som skaffer en tillatelse om gangen. På den annen side kan vi sende alle 100 byte samtidig og skaffe oss alle 100 tillatelsene i en operasjon.

4. Å skaffe tillatelser på en blokkerende måte

La oss nå vurdere et litt mer komplekst eksempel.

Vi lager en RateLimiter med 100 tillatelser. Så skal vi utføre en handling som må skaffe 1000 tillatelser. I henhold til spesifikasjonen til RateLimiter, slik handling vil trenge minst 10 sekunder for å fullføre fordi vi bare kan utføre 100 handlinger per sekund:

@Test offentlig ugyldighet givenLimitedResource_whenUseRateLimiter_thenShouldLimitPermits () {// gitt RateLimiter rateLimiter = RateLimiter.create (100); // når lang starttid = ZonedDateTime.now (). getSecond (); IntStream.range (0, 1000) .forEach (i -> {rateLimiter.acquire (); doSomeLimitedOperation ();}); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // deretter assertThat (elapsedTimeSeconds> = 10); }

Merk, hvordan vi bruker tilegne() metode her - dette er en blokkeringsmetode, og vi bør være forsiktige når vi bruker den. Når tilegne() metoden blir kalt, blokkerer den kjøringstråden til en tillatelse er tilgjengelig.

Ringer til tilegne() uten argument er det samme som å kalle det med ett som argument - den vil prøve å skaffe seg en tillatelse.

5. Å skaffe tillatelser med en tidsavbrudd

De RateLimiter API har også en veldig nyttig tilegne() metode som aksepterer a pause og TimeUnit som argumenter.

Å ringe til denne metoden når det ikke er tilgjengelige tillatelser, vil føre til at den venter på spesifisert tid og deretter tidsavbrudd - hvis det ikke er nok tilgjengelige tillatelser innenfor pause.

Når det ikke er tilgjengelige tillatelser innen gitt tidsavbrudd, returnerer den falsk. Hvis en tilegne() lykkes, det returnerer ekte:

@Test offentlig ugyldighet givenLimitedResource_whenTryAcquire_shouldNotBlockIndefinitely () {// gitt RateLimiter rateLimiter = RateLimiter.create (1); // når rateLimiter.acquire (); boolsk resultat = rateLimiter.tryAcquire (2, 10, TimeUnit.MILLISECONDS); // påstå deretter (resultat) .isFalse (); }

Vi opprettet en RateLimiter med en tillatelse, så det vil alltid føre til å prøve å skaffe to tillatelser tryAcquire () å returnere falsk.

6. Konklusjon

I denne raske opplæringen så vi på RateLimiter konstruere fra Guava bibliotek.

Vi lærte å bruke RateLimtiter for å begrense antall tillatelser per sekund. Vi så hvordan vi bruker det blokkerende API-et, og vi brukte også en eksplisitt tidsavbrudd for å skaffe tillatelsen.

Som alltid finnes implementeringen av alle disse eksemplene og kodebitene i GitHub-prosjektet - dette er et Maven-prosjekt, så det skal være enkelt å importere og kjøre som det er.


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