Panduan Pantas untuk Limit Kadar Jambu Batu

1. Gambaran keseluruhan

Dalam artikel ini, kita akan melihat kelas RateLimiter dari perpustakaan Jambu .

The RateLimiter kelas adalah konstruk yang membolehkan kita untuk mengawal kadar di mana beberapa pemprosesan berlaku. Sekiranya kita membuat RateLimiter dengan izin N - ini bermaksud proses boleh mengeluarkan paling banyak izin N sesaat.

2. Ketergantungan Maven

Kami akan menggunakan perpustakaan Jambu:

 com.google.guava guava 29.0-jre 

Versi terbaru boleh didapati di sini.

3. Membuat dan Menggunakan RateLimiter

Katakan bahawa kita mahu mengehadkan kadar pelaksanaan doSomeLimitedOperation () kepada 2 kali sesaat.

Kita boleh membuat instance RateLimiter menggunakan kaedah kilang create () :

RateLimiter rateLimiter = RateLimiter.create(2);

Seterusnya, untuk mendapatkan izin pelaksanaan dari RateLimiter, kita perlu memanggil kaedah memperoleh () :

rateLimiter.acquire(1);

Untuk memastikan ia berfungsi, kami akan membuat 2 panggilan seterusnya ke kaedah throttled:

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

Untuk mempermudah pengujian kami, anggap kaedah doSomeLimitedOperation () selesai dengan segera.

Dalam kes sedemikian, kedua-dua permohonan kaedah memperoleh () tidak boleh disekat dan masa yang berlalu harus kurang atau di bawah satu saat - kerana kedua-dua izin dapat diperoleh dengan segera:

assertThat(elapsedTimeSeconds <= 1);

Selain itu, kita dapat memperoleh semua izin dalam satu panggilan () :

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

Ini boleh berguna jika, misalnya, kita perlu menghantar 100 bait sesaat. Kami boleh menghantar seratus kali satu bait memperoleh satu izin pada satu masa. Sebaliknya, kita dapat menghantar semua 100 bait sekaligus memperoleh semua 100 izin dalam satu operasi.

4. Memperolehi Permit dengan Cara Menyekat

Sekarang, mari kita pertimbangkan contoh yang sedikit lebih kompleks.

Kami akan membuat RateLimiter dengan 100 izin. Kemudian kita akan melakukan tindakan yang perlu memperoleh 1000 izin. Mengikut spesifikasi RateLimiter, tindakan tersebut memerlukan masa sekurang-kurangnya 10 saat untuk diselesaikan kerana kami hanya dapat melakukan 100 unit tindakan sesaat:

@Test public void givenLimitedResource_whenUseRateLimiter_thenShouldLimitPermits() { // given 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; // then assertThat(elapsedTimeSeconds >= 10); }

Perhatikan, bagaimana kita menggunakan kaedah memperoleh () di sini - ini adalah kaedah menyekat dan kita harus berhati-hati ketika menggunakannya. Apabila kaedah memperoleh () dipanggil, ia menyekat benang pelaksana sehingga izin tersedia.

Memanggil pemeroleh () tanpa argumen adalah sama dengan memanggilnya dengan argumen - ia akan berusaha mendapatkan satu izin.

5. Memperolehi Permit Dengan Waktu Akhir

The RateLimiter API juga mempunyai sangat berguna memperoleh () kaedah yang menerima suatu had masa dan TimeUnit sebagai argumen.

Memanggil kaedah ini apabila tidak ada izin yang tersedia akan menyebabkannya menunggu masa yang ditentukan dan kemudian habis masa - jika tidak ada cukup izin yang tersedia dalam jangka masa tamat.

Apabila tidak ada izin yang tersedia dalam jangka masa yang ditentukan, ia akan menjadi salah. Sekiranya pemerolehan () berjaya, ia akan kembali benar:

@Test public void givenLimitedResource_whenTryAcquire_shouldNotBlockIndefinitely() { // given RateLimiter rateLimiter = RateLimiter.create(1); // when rateLimiter.acquire(); boolean result = rateLimiter.tryAcquire(2, 10, TimeUnit.MILLISECONDS); // then assertThat(result).isFalse(); }

Kami membuat RateLimiter dengan satu permit jadi cuba memperoleh dua izin akan selalu menyebabkan tryAcquire () kembali palsu.

6. Kesimpulannya

Dalam tutorial ringkas ini, kami melihat konstruk RateLimiter dari perpustakaan Jambu .

Kami belajar bagaimana menggunakan RateLimtiter untuk membatasi jumlah izin sesaat. Kami melihat bagaimana menggunakan API pencekalannya dan kami juga menggunakan batas waktu eksplisit untuk mendapatkan izin.

Seperti biasa, pelaksanaan semua contoh dan potongan kode ini terdapat dalam projek GitHub - ini adalah projek Maven, jadi mudah untuk diimport dan dijalankan sebagaimana adanya.