UNDER PRESSURE

Level 1 · Menggandakan Mesin

Sesi 11: Satu Pintu untuk Semua: Reverse Proxy, Buffering, & Rate Limiting

Bagaimana jika ada satu pengunjung yang mengisi formulir sangat lambat, dan petugas pintu harus menunggu dia selesai sebelum melayani orang lain? Apa yang terjadi jika 1.000 pengunjung lambat itu datang sekaligus?

Sesi 11 / 344 menit baca

1. Reverse Proxy vs Load Balancer: Dua Peran, Sering Satu Produk

Load Balancer fokus pada distribusi beban ke banyak server backend. Reverse Proxy fokus pada terminasi koneksi klien, buffering, caching, kompresi, dan proteksi.

Dalam praktik modern (NGINX, HAProxy, Envoy, AWS ALB, Cloudflare), kedua peran ini sering berada di satu biner/layanan yang sama. Produk itu menerima request dari internet, bertindak sebagai reverse proxy (terminasi TLS, baca HTTP), lalu meneruskan ke backend pool sebagai load balancer.

INTERNET
    │
    ▼
┌─────────────────────────────┐
│  REVERSE PROXY / LB (NGINX) │  ◄── SATU PINTU MASUK
└──────────────┬──────────────┘
    │           │
    │ TLS Term  │ Buffering & Compression
    ▼           ▼
┌─────────────────────────────┐
│   BACKEND APPLICATION       │
└─────────────────────────────┘

2. Masalah Klien Lambat (Slow Client / Slowloris)

Salah satu bahaya tersembunyi paling besar bagi server aplikasi adalah Slow Client — klien yang mengirim request pelan-pelan (misal 1 byte per detik) atau membaca response dengan sangat lambat.

Tanpa Reverse Proxy (Direct to App):

Klien Lambat ──(TCP Connection Tertahan)──► Worker Thread App (TERBLOKIR)
  • Setiap koneksi lambat menghabiskan 1 thread/worker di server aplikasi (Gunicorn, Node.js event loop, PHP-FPM).
  • Cukup ratusan klien lambat untuk melumpuhkan seluruh kapasitas server (Slowloris attack atau unintentional DoS dari jaringan mobile buruk).

Dengan Reverse Proxy (Buffering):

Klien Lambat ──► Reverse Proxy (BUFFER PENUH) ──► Backend (CEPAT)
                     │
              [Menyimpan seluruh request
               di memory/disk buffer]
  • Reverse proxy menangkap seluruh request lambat di buffer-nya (memory atau disk).
  • Hanya setelah request utuh dan selesai, proxy meneruskannya ke backend dalam sekali burst cepat.
  • Backend worker hanya tersedot waktu proses logika bisnis, bukan waktu tunggu jaringan klien.

3. Request/Response Buffering

Jenis Deskripsi Kenapa Penting
Request Buffering Proxy baca seluruh body request dari klien lambat, baru kirim ke backend Melindungi backend dari Slow Client / Slowloris
Response Buffering Proxy terima response utuh dari backend cepat, baru kirim perlahan ke klien Backend bebaskan thread secepatnya; klien lambat jadi masalah proxy

Konfigurasi Kritis NGINX:

# Buffer request body (default on)
client_body_buffer_size 16k;       # Memory buffer sebelum spill ke disk
client_max_body_size 10m;          # Batasi ukuran upload

# Buffer response dari backend
proxy_buffering on;
proxy_buffers 8 16k;               # 8 buffer x 16KB = 128KB memory
proxy_busy_buffers_size 32k;       # Buffer yang dikirim ke klien

4. Static Offload & Kompresi: Tugas Proxy, Bukan App

Jangan biarkan aplikasi backend (Python, Node, Go, Java) melayani file statis (CSS, JS, gambar, font) atau melakukan kompresi Gzip/Brotli. Itu membuang CPU mahal dan thread worker.

Di Reverse Proxy (Lakukan Di Sini):

  1. Static File Serving: nginx location /static/ { alias /var/www/assets/; expires 1y; add_header Cache-Control "public, immutable"; }
  2. Kompresi (Gzip / Brotli): nginx gzip on; gzip_types text/css application/javascript application/json; brotli on; brotli_types text/css application/javascript;
  3. Cache-Control Header: - Cache-Control: public, max-age=31536000, immutable untuk asset yang di-hash filename-nya. - Cache-Control: no-store untuk HTML dinamis / API.

Hasil:

  • > 90% traffic statis dilayani langsung oleh proxy tanpa pernah menyentuh aplikasi backend.
  • Backend hanya fokus pada business logic (API, DB query, auth).

5. Rate Limiting: Lapisan Pertahanan Pertama

Sebelum request sampai ke logika bisnis (yang mahal: query DB, hit Redis, hit service lain), batasi di pintu masuk.

Algoritma Token Bucket / Leaky Bucket:

  • Setiap IP/user mendapat "token" tiap detik (misal 10 req/detik).
  • Request tanpa token → HTTP 429 Too Many Requests (dihentikan di proxy, backend tidak tersentuh).
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

location /api/ {
    limit_req zone=api_limit burst=20 nodelay;
    # burst=20: izinkan lonjakan 20 req sekaligus
    # nodelay: jangan delay, tolak langsung jika melebihi burst
}

Tingkat Perlindungan:

Level Target Contoh
Edge / CDN DDoS Volumetric, Bot Cloudflare, AWS Shield
Reverse Proxy (L7) API Abuse, Brute Force, Crawler NGINX limit_req, HAProxy stick-table
Application Business Logic Abuse Custom middleware (login attempts, password reset)

6. Health Check & Circuit Breaker di Level Proxy

Reverse Proxy juga bisa melakukan passive health check: - Jika backend return 5xx atau timeout berulang → tandai DOWN. - Hentikan kirim traffic ke node itu (circuit breaker). - Lanjutkan health check aktif secara berkala; hidupkan kembali saat pulih.

upstream backend {
    server 10.0.1.10:80 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:80 max_fails=3 fail_timeout=30s;
}

7. Ringkasan: Reverse Proxy sebagai "Gerbang"

Fungsi Dilakukan di Proxy (Murah) Bukan di App (Mahal)
TLS Termination ✅ ❌
Request Buffering (Anti Slow Client) ✅ ❌
Response Buffering (Bebaskan Worker) ✅ ❌
Static File Serving ✅ ❌
Gzip / Brotli Compression ✅ ❌
Rate Limiting (Token Bucket) ✅ ❌
Path Routing ke Microservices ✅ ❌
Access Log & Metrics ✅ ❌

Filosofi: Backend application harus hanya menjalankan business logic. Segala hal infrastruktur (network, protocol, protection) ditangani di lapisan depan.


8. Istilah Kunci

  • Reverse Proxy: Server yang menerima request dari klien dan meneruskan ke backend (satu arah: in → out).
  • Forward Proxy: Proxy yang digunakan klien untuk keluar ke internet (out → in) — bukan topik ini.
  • Request Buffering: Menampung seluruh request klien lambat sebelum forwarding ke backend.
  • Slow Client / Slowloris: Klien yang sengaja/tidak sengaja mengirim data sangat pelan untuk menghabiskan resource server.
  • Static Offload: Menyajikan file statis (CSS, JS, img) langsung dari proxy/CDN.
  • Rate Limiting: Membatasi jumlah request per satuan waktu per klien (IP / User ID).
  • Circuit Breaker: Otomatis menghentikan traffic ke backend yang gagal berulang.