Rövid útmutató a Guava RateLimiter használatához

1. Áttekintés

Ebben a cikkben megnézzük a RateLimiter osztály a Gujávafa könyvtár.

A RateLimiter osztály olyan konstrukció, amely lehetővé teszi számunkra, hogy szabályozzuk bizonyos feldolgozás sebességét. Ha létrehozunk egy RateLimiter N engedéllyel - ez azt jelenti, hogy a folyamat másodpercenként legfeljebb N engedélyt adhat ki.

2. Maven-függőség

Guava könyvtárát fogjuk használni:

 com.google.guava guava 29.0-jre 

A legújabb verzió itt található.

3. Létrehozás és felhasználás RateLimiter

Mondjuk, hogy szeretnénk korlátozza a doSomeLimitedOperation () másodpercenként 2-szer.

Hozhatunk létre a RateLimiter példánya annak teremt() gyári módszer:

RateLimiter rateLimiter = RateLimiter.create (2);

Ezután a végrehajtási engedély megszerzéséhez a RateLimiter, hívnunk kell a szerez() módszer:

rateLimiter.acquire (1);

Annak ellenőrzésére, hogy működik-e, 2 további hívást fogunk indítani a fojtott módszerrel:

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

Tesztelésünk egyszerűsítése érdekében tegyük fel, hogy doSomeLimitedOperation () módszer azonnal befejeződik.

Ebben az esetben a szerez() A módszer nem blokkolható, és az eltelt időnek kevesebbnek vagy kevesebbnek kell lennie, mint egy másodperc - mert mindkét engedély azonnal megszerezhető:

assertThat (elapsedTimeSeconds <= 1);

Ezenkívül minden engedélyt egyben szerezhetünk be szerez() hívás:

@Test public void givenLimitedResource_whenRequestOnce_thenShouldPermitWithoutBlocking () {// megadott RateLimiter rateLimiter = RateLimiter.create (100); // when long startTime = ZonedDateTime.now (). getSecond (); rateLimiter.acquire (100); doSomeLimitedOperation (); long elapsedTimeSeconds = ZonedDateTime.now (). getSecond () - startTime; // majd assertThat (elapsedTimeSeconds <= 1); }

Ez akkor lehet hasznos, ha például másodpercenként 100 bájtot kell küldenünk. Százszor küldhetünk egy bájtot, egyszerre egy engedély megszerzésével. Másrészt mind a 100 bájtot egyszerre elküldhetjük, és mind a 100 engedélyt megszerezhetjük egy művelet során.

4. Engedélyek megszerzése blokkoló módon

Vegyünk egy kissé összetettebb példát.

Létrehozunk egy RateLimiter 100 engedéllyel. Ezután végrehajtunk egy műveletet, amelynek 1000 engedély megszerzéséhez van szükség. A. Specifikációja szerint RateLimiter, az ilyen műveletek végrehajtásához legalább 10 másodpercre van szükség, mert másodpercenként csak 100 műveletegységet tudunk végrehajtani:

@Test public void givenLimitedResource_whenUseRateLimiter_thenShouldLimitPermits () {// megadott 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; // majd állítsaThat (elapsedTimeSeconds> = 10); }

Ne feledje, hogyan használjuk a szerez() módszer itt - ez egy blokkoló módszer, és óvatosnak kell lennünk a használatakor. Amikor az szerez() metódust hívják meg, blokkolja a végrehajtó szálat, amíg engedély nem áll rendelkezésre.

Felhívás a szerez() argumentum nélkül megegyezik azzal, hogy argumentumként hívjuk meg eggyel - megpróbál megszerezni egy engedélyt.

5. Engedélyek megszerzése időkorláttal

A RateLimiter Az API szintén nagyon hasznos szerez() módszer, hogy elfogadja a időtúllépés és TimeUnit mint érvek.

Ha ezt a módszert akkor hívja meg, ha nincs rendelkezésre álló engedély, akkor az meghatározott időt vár, majd időtúllépés - ha nincs elegendő rendelkezésre álló engedély a időtúllépés.

Ha az adott időkorláton belül nem állnak rendelkezésre engedélyek, akkor visszatér hamis. Ha egy szerez() sikerül, ez visszatér igaz:

@Test public void givenLimitedResource_whenTryAcquire_shouldNotBlockIndefinitely () {// megadott RateLimiter rateLimiter = RateLimiter.create (1); // amikor rateLimiter.acquire (); logikai eredmény = rateLimiter.tryAcquire (2, 10, TimeUnit.MILLISECONDS); // majd állítsaThat (eredmény) .isFalse (); }

Létrehoztuk a RateLimiter egy engedéllyel, így két engedély megszerzése mindig okozni fog tryAcquire () visszatérni hamis.

6. Következtetés

Ebben a gyors bemutatóban megnéztük a RateLimiter konstruálni a Gujávafa könyvtár.

Megtanultuk a RateLimtiter másodpercenként korlátozni az engedélyek számát. Láttuk, hogyan kell használni a blokkoló API-t, és kifejezett időtúllépést is alkalmaztunk az engedély megszerzéséhez.

Mint mindig, ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.