Kratki vodič za Guava RateLimiter

1. Pregled

U ovom ćemo članku pogledati RateLimiter razred iz Guava knjižnica.

The RateLimiter klasa je konstrukcija koja nam omogućuje reguliranje brzine kojom se događa neka obrada. Ako stvorimo a RateLimiter s N dozvola - znači da postupak može izdati najviše N dozvola u sekundi.

2. Ovisnost Mavena

Koristit ćemo Guavinu knjižnicu:

 com.google.guava guava 29,0-jre 

Najnoviju verziju možete pronaći ovdje.

3. Stvaranje i korištenje RateLimiter

Recimo da želimo ograničiti brzinu izvršenja doSomeLimitedOperation () do 2 puta u sekundi.

Možemo stvoriti RateLimiter primjerice koristeći svoj stvoriti() tvornička metoda:

RateLimiter rateLimiter = RateLimiter.create (2);

Dalje, kako bi se od RateLimiter, moramo nazvati steći() metoda:

rateLimiter.acquire (1);

Kako bismo provjerili radi li, izvršit ćemo dva sljedeća poziva na prigušenu metodu:

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

Da pojednostavimo naše testiranje, pretpostavimo to doSomeLimitedOperation () metoda se dovršava odmah.

U tom slučaju, oba poziva na steći() metoda ne smije blokirati, a proteklo vrijeme treba biti manje ili manje od jedne sekunde - jer se obje dozvole mogu dobiti odmah:

assertThat (protekloTimeSekunde <= 1);

Uz to, sve dozvole možemo dobiti u jednom steći() poziv:

@Test javna praznina givenLimitedResource_whenRequestOnce_thenShouldPermitWithoutBlocking () {// zadana RateLimiter rateLimiter = RateLimiter.create (100); // kada je dugo startTime = ZonedDateTime.now (). getSecond (); rateLimiter.acquire (100); doSomeLimitedOperation (); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // zatim assertThat (elapsedTimeSeconds <= 1); }

To može biti korisno ako, na primjer, trebamo poslati 100 bajtova u sekundi. Odjednom možemo poslati sto puta po jedan bajt stječući jednu dozvolu. S druge strane, možemo poslati svih 100 bajtova odjednom stječući svih 100 dozvola u jednoj operaciji.

4. Dobivanje dozvola na blokirajući način

Razmotrimo sada malo složeniji primjer.

Stvorit ćemo a RateLimiter sa 100 dozvola. Tada ćemo izvršiti akciju koja treba dobiti 1000 dozvola. Prema specifikaciji RateLimiter, za takvu će akciju trebati najmanje 10 sekundi da bismo dovršili jer smo u mogućnosti izvršiti samo 100 jedinica akcije u sekundi:

@Test javna praznina givenLimitedResource_whenUseRateLimiter_thenShouldLimitPermits () {// zadana RateLimiter rateLimiter = RateLimiter.create (100); // kada je dugo startTime = ZonedDateTime.now (). getSecond (); IntStream.range (0, 1000) .forEach (i -> {rateLimiter.acquire (); doSomeLimitedOperation ();}); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // zatim assertThat (elapsedTimeSeconds> = 10); }

Napomena: kako koristimo steći() metoda ovdje - ovo je metoda blokiranja i trebali bismo biti oprezni kada je koristimo. Kada steći() metoda se poziva, ona blokira izvršnu nit dok ne bude dostupna dozvola.

Pozivanje steći() bez argumenta isto je što i nazvati ga s jednim kao argument - pokušat će dobiti jednu dozvolu.

5. Pribavljanje dozvola s vremenskim ograničenjem

The RateLimiter API ima i vrlo koristan steći() metoda koja prihvaća a pauza i TimeUnit kao argumenti.

Pozivanje ove metode kada nema dostupnih dozvola prouzročit će da pričeka određeno vrijeme, a zatim istekne - ako unutar računa nema dovoljno dostupnih dozvola pauza.

Kada nema raspoloživih dozvola u zadanom vremenskom ograničenju, vraća se lažno. Ako an steći() uspije, to vraća se pravi:

@Test javna praznina givenLimitedResource_whenTryAcquire_shouldNotBlockIndefinitely () {// zadana RateLimiter rateLimiter = RateLimiter.create (1); // kada rateLimiter.acquire (); logički rezultat = rateLimiter.tryAcquire (2, 10, TimeUnit.MILLISECONDS); // zatim assertThat (rezultat) .isFalse (); }

Stvorili smo RateLimiter s jednom dozvolom, pa će pokušaj pribavljanja dviju dozvola uvijek uzrokovati tryAcquire () vratiti lažno.

6. Zaključak

U ovom smo brzom vodiču pogledali RateLimiter konstruirati iz Guava knjižnica.

Naučili smo kako koristiti OcijeniLimtiter ograničiti broj dozvola u sekundi. Vidjeli smo kako se koristi njegov API za blokiranje, a koristili smo i izričito vrijeme čekanja za dobivanje dozvole.

Kao i uvijek, implementacija svih ovih primjera i isječaka koda može se naći u projektu GitHub - ovo je Maven projekt, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.