Level 3 · Sistem yang Saling Bergantung
Sesi 28: Membatasi Arus: Rate Limiting, Leaky Bucket, & Token Bucket
Bagaimana jika kemampuan paling penting dari sebuah sistem berkapasitas tinggi bukanlah kemampuannya melayani semua permintaan, melainkan keberaniannya mengatakan "TIDAK" kepada 10% permintaan berlebih demi menyelamatkan 90% pengguna lainnya?
1. Bayangkan Jika
Sebuah klub malam mewah hanya memiliki kapasitas 200 orang di dalam ruangan. Di depan pintu masuk, berdiri seorang satpam bertubuh kekar dengan tali pembatas antrean: - Jika ada 500 orang mabuk memaksa merangsek masuk bersamaan, satpam tidak membiarkan semua orang masuk (karena jika masuk, lantai dansa roboh dan semua orang terluka). - Satpam hanya mengizinkan orang masuk sesuai ketersediaan gelang tiket (Token Bucket), atau melepas 1 orang masuk setiap 5 detik secara teratur (Leaky Bucket). Sisa orang di luar diberi tahu secara sopan: "Tunggu giliran, kembali lagi 10 menit lagi" (HTTP 429 Too Many Requests).
2. Apa yang Sebenarnya Terjadi
Tanpa pembatas arus (Rate Limiter), sistem sangat rentan terhadap: - Serangan DDoS Lapis 7 (HTTP Flood). - Scraper / Bot Liar yang menyedot database katalog 500 kali per detik. - Pengguna yang tidak sengaja menjalankan script loop tanpa jeda.
Ketika server menerima beban di luar kapasitas puncaknya, latensi melonjak tajam dan server kolaps. Rate Limiting bertindak sebagai perisai di pintu terluar (Reverse Proxy / API Gateway).
3. Empat Algoritma Pembatas Arus
-
Fixed Window Counter: - Batasi 100 request per menit (00:00 - 01:00). - Kelemahan (Boundary Burst): Jika ada 100 request di detik 00:59 dan 100 request di detik 01:01, server dihantam 200 request dalam 2 detik!
-
Sliding Window Log / Counter: - Menghitung jumlah request dalam jendela geser 60 detik terakhir secara presisi menggunakan timestamp. Menghilangkan celah lonjakan perbatasan (boundary burst).
-
Token Bucket: - Ember memiliki kapasitas maksimal B token. Token diisi ulang secara konstan sebesar R token/detik. - Setiap request masuk harus mengambil 1 token. Jika ember kosong \rightarrow
429 Too Many Requests. - Keunggulan: Mengizinkan traffic burst singkat (selama token di ember masih ada), lalu membatasi laju rata-rata. -
Leaky Bucket: - Request masuk ke ember dan dikeluarkan dengan kecepatan konstan seperti keran bocor. - Keunggulan: Menghasilkan aliran trafik keluar yang sangat mulus tanpa lonjakan sama sekali (smooth constant outflow).
4. Distributed Rate Limiter dengan Redis
Dalam sistem multi-server, rate limiter harus bersifat global dan terpusat:
- Redis Atomic Counter & Lua Scripting:
- Jangan gunakan GET lalu SET di kode aplikasi (rentan race condition).
- Gunakan Redis Lua Script atau modul redis-cell untuk mengeksekusi Token Bucket secara atomik dalam <1 milidetik.
- Header Standar Respons HTTP:
HTTP/1.1 429 Too Many RequestsRetry-After: 30(Coba lagi dalam 30 detik)X-RateLimit-Limit: 100(Batas kuota)X-RateLimit-Remaining: 0(Sisa kuota)
5. Nama Resminya
- Rate Limiting: Kontrol laju trafik jaringan yang masuk atau keluar dari sebuah antarmuka layanan.
- HTTP 429: Kode status standar HTTP yang menunjukkan klien telah melampaui kuota permintaan yang diizinkan dalam rentang waktu tertentu.
- Token Bucket Algorithm: Algoritma kontrol paket yang memungkinkan burst terkendali berdasarkan deposit token.
- Leaky Bucket Algorithm: Algoritma kontrol laju yang menstandarkan kecepatan keluaran menjadi konstan.
6. Di Dunia Kita
- GitHub / OpenAI API: Menerapkan pembatasan ketat (misal: Tier 1 OpenAI = 500 RPM / 30.000 TPM) dengan header
X-RateLimit-*. - Cloudflare / AWS WAF: Rate limiting berbasis IP dan fingerprint TLS di tepi jaringan (edge).
7. Lensa Performance Tester
Metrik dan pengujian krusial:
1. Burst Capacity vs Throttling: Tembakkan 500 request dalam 100 ms ke endpoint berkuota 100 RPM. Pastikan tepat 100 request lolos (200 OK) dan 400 request lainnya ditolak dengan status 429.
2. Distributed Redis Latency: Ukur overhead latensi pengecekan token di Redis: harus di bawah 2 milidetik pada beban 10.000 QPS.
3. Retry-After Header Accuracy: Pastikan klien yang menunggu sesuai detik di header Retry-After mendapatkan status 200 OK pada request berikutnya.
8. Pertanyaan untuk Ronde Berikutnya
Ketika sistem kita sudah terlindungi dari banjir request, bagaimana jika kita ingin menguji batas kekuatannya sebelum bencana nyata terjadi di hari peluncuran produk?
Jawabannya ada di Sesi 29: Menembak Server Sendiri: Load Testing, Spike Testing, & Chaos Engineering.