Belajar Site Reliability Engineer - Distributed Systems Reliability
Episode 21 of 28

Belajar Site Reliability Engineer - Distributed Systems Reliability

Menghadapi kenyataan bahwa jaringan bisa gagal di tengah jalan: teorema CAP dan konsistensi, partitioning, retry dengan backoff yang benar, circuit breaker, hingga idempotency — dibuktikan dengan praktik menerapkan pola resiliency langsung dalam kode

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Semua episode sebelumnya mengasumsikan satu hal yang ternyata salah: bahwa ketika kalian memanggil service lain, ia selalu merespons. Kenyataan sistem terdistribusi lebih kasar — jaringan bisa menunda paket, memutus koneksi, dan mengirim respons ganda. Kode yang ditulis untuk dunia "selalu berhasil" akan gagal di dunia nyata, bukan karena bug, tapi karena asumsi.

Distributed systems reliability adalah keterampilan menulis kode yang toleran terhadap kenyataan. Episode 21 membahas konsistensi, partitioning, retry/backoff, circuit breaker, dan idempotency — lima pola yang mengubah service dari rapuh menjadi tangguh di jaringan yang tidak bisa dipercaya.

CAP & Partisi: Memilih Kegagalan yang Paling Elegan

Teorema CAP menyatakan sistem terdistribusi hanya bisa menjamin dua dari tiga: Consistency (semua node melihat data sama), Availability (setiap request mendapat respons), dan Partition tolerance (sistem tetap jalan saat jaringan terbelah). Karena network partition (P) tidak bisa dicegah, pilihan nyata tinggal dua: saat jaringan terbelah, sistem CP mengorbankan ketersediaan demi konsistensi, dan sistem AP mengorbankan konsistensi demi tetap melayani.

100%

Pilihan ini harus sadar dan tercatat, bukan kebetulan arsitektur: database yang kuat konsistensinya (PostgreSQL, Spanner) adalah CP; system yang akhirnya konsisten (Cassandra, DynamoDB mode default) adalah AP. Kalian harus bisa menjawab dengan satu kalimat: saat node terisolasi, sistem kita memilih menolak tulis atau menerima tulis yang mungkin basi?

Retry dengan Backoff: Jangan Memperbesar Kegagalan

Ketika satu request gagal, godaan pertama adalah mencoba lagi segera. Itu justru pola paling berbahaya: jika dependency sedang mati, ribuan request yang me-retry serentak menghasilkan retry storm yang menghabisi dependency yang sedang berusaha pulih.

Aturan retry yang sehat:

  • Exponential backoff: jeda naik bertahap (1s → 2s → 4s → 8s).
  • Jitter: tambahkan acakan pada jeda agar retry tidak terjadi serentak — tiga klien dengan backoff yang sama akan menabrak lagi secara bersamaan.
  • Batas retry yang kecil: retry 3-5 kali, lalu menyerah — bukan retry tanpa henti.
  • Jangan retry request yang bukan idempotent tanpa perlindungan idempotency key (di bawah).
Contoh jeda retry dengan jitter (dalam detik)
Attempt 1: 1.0 + 0.4 jitter = 1.4
Attempt 2: 2.0 + 1.1 jitter = 3.1
Attempt 3: 4.0 + 0.6 jitter = 4.6
Attempt 4: 8.0 + 2.3 jitter = 10.3
Attempt 5: menyerah -> panggil fallback

Circuit Breaker: Gagal dengan Cepat, Pulih dengan Aman

Retry menyelamatkan kegagalan sementara; circuit breaker menyelamatkan dari kegagalan berkepanjangan. Idenya dipinjam dari listrik: jika kegagalan melampaui ambang batas, putuskan aliran — request langsung ditolak tanpa memanggil dependency, memberi waktu dependency pulih.

Tiga status circuit breaker
CLOSED   -> semua request diteruskan (normal)
OPEN     -> request ditolak langsung (dependency sakit)
HALF-OPEN-> kirim beberapa percobaan uji (uji pemulihan)

Manfaat gandanya: dependency yang sedang kolaps tidak dibebani request yang hanya akan menunggu timeout, dan aplikasi merespons cepat dengan error yang jelas alih-alih menggantung sampai timeout.

Idempotency: Menjalankan Dua Kali = Sekali Efek

Retry memunculkan pertanyaan mengerikan: bagaimana jika request pertama berhasil diproses tetapi responsnya hilang? Kalau klien me-retry, operasi yang sama (bayar, transfer, kirim email) bisa terjadi dua kali. Idempotency menjawabnya: operasi boleh dijalankan berulang, tetapi efeknya hanya terjadi sekali.

Implementasi paling umum adalah idempotency key: klien mengirim Idempotency-Key unik, server menyimpan hasil pertama kali key itu diproses, dan untuk key yang sama mengembalikan respons tersimpan tanpa mengeksekusi ulang.

idempotency.ts (contoh konsep)
async function processPayment(key, amount) {
  const seen = await idemStore.get(key);
  if (seen) return seen;                    // sudah diproses -> balas hasil lama
 
  const result = await charge(amount);      // baru: proses sekali
  await idemStore.set(key, result, { ttl: "24h" });
  return result;
}

Pola ini wajib untuk mutasi yang penting (pembayaran, transfer, event). Read tidak butuh idempotency; create dan update paling butuh.

Praktik: Pola Resiliency dalam Kode

Gabungkan kelima pola pada service lab kalian yang memanggil dependency eksternal:

  1. Bungkus semua panggilan ke dependency dengan client yang punya timeout eksplisit (misal 2 detik) — tanpa timeout, retry hanya menumpuk kegagalan yang menggantung.
  2. Tambahkan retry exponential + jitter untuk kegagalan yang mungkin sementara (timeout, 5xx), dengan batas 3 percobaan.
  3. Pasang circuit breaker pada dependency yang mahal/kritis (status OPEN setelah 5 kegagalan dalam 30 detik).
  4. Terapkan idempotency key pada satu endpoint mutasi penting.
  5. Uji dengan chaos (episode 13): matikan dependency, amati service menjawab cepat dengan error yang jelas — bukan menggantung sampai timeout.
Uji: dependency dimatikan, service harus fail fast
# dependency sengaja dimatikan
docker stop dependency-service
 
# request harus ditolak cepat (bukan menggantung)
time curl -s http://localhost:8080/checkout
# -> respons error < 500ms setelah breaker OPEN

Tip

Mulailah dari satu pola yang paling berdampak: timeout eksplisit — ini murah, mudah, dan langsung menghilangkan sebagian besar masalah "menggantung". Setelah timeout konsisten, tambahkan retry + jitter, lalu breaker, lalu idempotency. Menerapkan kelimanya sekaligus di tengah migrasi justru membuat sulit menemukan akar masalah.

Penutup

Pada episode 21 ini, kalian telah belajar menulis kode yang memercayai kegagalan sebagai bagian dari desain.

Inti yang harus dibawa pulang:

  • CAP memaksa pilihan sadar antara CP dan AP saat jaringan terbelah.
  • Retry + exponential backoff + jitter mencegah retry storm.
  • Circuit breaker membuat kegagalan cepat dan memberi dependency ruang pulih.
  • Idempotency key membuat operasi yang dijalankan dua kali hanya berefek sekali.
  • Kelima pola membentuk satu lapisan: tanpa timeout, pola lain justru menambah masalah.

Di episode 22 selanjutnya, kita akan menggandeng AI: AI-assisted operations — anomaly detection, auto-remediation, dan predictive scaling untuk operasi yang semakin otomatis. Sampai jumpa di episode 22!