Lompat ke konten
20 menit bacamateri 11 dari 96

Alihkan trafik dari server yang tidak sehat

Strategi load balancing, health check, koneksi yang dipakai ulang, dan session affinity: cara menarik instance yang sakit tanpa memperparah keadaan.

Ditinjau 26 Oktober 2026

Pertanyaan

Bagaimana load balancer memilih instance, mengetahui instance itu sakit, dan berhenti mengirim trafik ke sana tanpa membuat sisanya kewalahan?

Setelah baca ini, kamu bisa memilih algoritma load balancing untuk sebuah beban, merancang health check dengan ambang yang masuk akal, dan menjelaskan kapan session affinity membantu atau merusak.

Prasyarat dan contoh

Kamu sudah tahu peran load balancer L4 dan L7 (M02.04) dan batas konkurensi sebuah instance (M02.03).

Lima instance, masing-masing sanggup 200 request/detik, beban 600 request/detik, jadi tiap instance 120 (60 persen). Satu instance mulai macet karena memori penuh. Kalau load balancer tidak sadar, 120 request/detik terus mengalir ke instance yang membalas dalam 8 detik atau tidak sama sekali. Kalau ia menariknya, empat sisanya menerima 150 request/detik (75 persen). Masih aman, tapi margin turun.

Mekanisme

Algoritma pemilihan.

  • Round robin: bergiliran. Sederhana, adil kalau semua request kira-kira sama berat dan instance sama kuat.
  • Weighted round robin: bobot per instance, untuk mesin yang berbeda ukuran.
  • Least connections / least outstanding requests: pilih instance dengan request aktif paling sedikit. Lebih baik saat durasi request sangat bervariasi, karena instance yang tersangkut otomatis menerima lebih sedikit.
  • Hash (misalnya IP atau header): request dengan kunci sama ke instance sama. Dasar untuk affinity dan cache lokal.
  • Power of two choices: ambil dua instance acak, pilih yang lebih sepi. Hampir sebaik least connections dengan koordinasi yang jauh lebih sedikit.

Health check. Dua jenis yang melengkapi:

  • Aktif: load balancer memanggil endpoint (misalnya /health) tiap 5 detik. Instance dianggap sakit setelah 3 kegagalan beruntun, sehat lagi setelah 2 sukses. Deteksi terburuk: 3 × 5 = 15 detik, selama itu sekitar 15 detik × 120 = 1.800 request bisa terkirim ke instance sakit.
  • Pasif: load balancer mengamati trafik asli. Jika 5 respons beruntun adalah 5xx atau timeout, instance dikeluarkan sementara. Lebih cepat (hitungan detik pada beban tinggi), tapi hanya bereaksi setelah user terdampak.

Pilih ambang dengan sadar: terlalu sensitif menyebabkan instance keluar-masuk (flapping) karena satu timeout; terlalu longgar membiarkan instance sakit lama.

Apa yang diperiksa /health. Ada dua pertanyaan berbeda. Liveness: proses hidup? Readiness: siap melayani? Readiness yang memeriksa database akan menarik semua instance sekaligus kalau database lambat. Akibatnya total outage padahal aplikasinya sendiri baik. Readiness sebaiknya memeriksa hal yang spesifik ke instance itu (selesai warm-up, pool tidak habis), bukan dependensi bersama.

Menarik dan mengembalikan dengan halus. Saat deploy atau penarikan, gunakan connection draining: berhenti menerima request baru, biarkan yang berjalan selesai (batas mis. 30 detik). Instance yang baru dimulai perlu slow start: bobot naik bertahap, karena cache dan JIT masih dingin.

Koneksi yang dipakai ulang. Koneksi keep-alive atau HTTP/2 yang panjang menempel ke satu instance. LB L4 membagi per koneksi, bukan per request, jadi 3 klien besar dengan 1 koneksi HTTP/2 tiap klien bisa mendarat di instance yang sama. Instance baru yang ditambah saat lonjakan tidak menerima apa pun karena semua koneksi sudah terbentuk. Solusi: LB L7 yang membagi per request, batas umur koneksi (mis. tutup setelah 5 menit atau 10.000 request), atau klien yang membuka koneksi ke beberapa instance.

Session affinity (sticky session). Request dari klien yang sama selalu ke instance yang sama, lewat cookie atau hash. Berguna kalau state ada di memori lokal atau cache lokal berharga. Harganya: beban tidak merata (satu klien berat menempel ke satu instance), dan instance yang mati menghilangkan state klien yang menempel padanya.

Saat rancangan ini gagal

  • Health check terlalu dangkal. /health selalu 200 karena hanya mengembalikan string, padahal pool koneksi sudah habis. Instance sakit tetap menerima trafik.
  • Health check terlalu dalam. Memeriksa database dan semua dependensi. Database lambat 2 detik, semua instance dinyatakan sakit, tidak ada yang melayani.
  • Menarik instance memperparah. Dari lima instance, dua ditarik: tiga sisanya harus menanggung 200 request/detik tiap instance (100 persen), mulai antre, gagal health check, ditarik juga. Kegagalan beruntun. Batasi persentase instance yang boleh ditarik (mis. maksimal 50 persen, panic mode: bila lebih banyak, kirim ke semua).
  • Retry badai. Instance gagal, klien dan proxy retry ke instance lain, beban efektif naik 2× di instance yang masih sehat. Retry perlu anggaran (M03).
  • Flapping. Instance hidup-mati tiap 10 detik karena ambang terlalu sensitif, memutus koneksi terus-menerus.
  • Koneksi panjang tidak seimbang. Setelah deploy, instance yang paling awal restart memegang paling sedikit koneksi, instance terakhir paling banyak.
  • Affinity dengan instance mati. User kehilangan sesi tepat saat sistem sedang tidak stabil.

Contoh tandingan: round robin murni untuk request yang durasinya 5 ms sampai 5 detik. Satu instance kebetulan menerima beberapa request berat berturut-turut dan antreannya tumbuh, padahal ada instance lain yang kosong.

Latihan

Enam instance, tiap instance maksimum 100 request/detik, beban 450 request/detik (75 persen). Health check aktif tiap 5 detik, 3 gagal beruntun untuk keluar. Dua instance gagal bersamaan pada waktu yang sama.

  1. Berapa utilisasi sisa instance setelah keduanya ditarik?
  2. Apa yang kamu ubah supaya tidak terjadi kegagalan beruntun?
  3. Berapa request kira-kira yang terkirim ke instance sakit sebelum keduanya ditarik?
Lihat pembahasan
  1. Sisa 4 instance: 450 / 4 = 112,5 request/detik per instance, atau 112,5 persen dari maksimum 100. Mereka kelebihan beban, mulai antre, dan bisa gagal health check, sehingga kegagalan menjalar.
  2. Beberapa langkah: (a) sisakan kapasitas, misalnya 8 instance. Beban 450 tetap 56 persen saat normal, dan kehilangan dua instance menyisakan 450 / 6 = 75 request/detik per instance, masih di bawah 100; (b) terapkan batas penarikan agar load balancer tidak menarik lebih dari sebagian tertentu dan pindah ke mode kirim ke semua; (c) shed load (tolak cepat dengan 503 saat antrean melewati batas) supaya instance sehat tidak ikut roboh; (d) pastikan retry di klien punya anggaran.
  3. Deteksi terburuk = 3 × 5 = 15 detik. Tiap instance menerima 450 / 6 = 75 request/detik, jadi dua instance menerima sekitar 2 × 75 × 15 = 2.250 request. Pasif health check bisa memotong ini menjadi beberapa detik.

Jawaban yang bagus menghitung sisa kapasitas, bukan hanya menyebut "tambah health check".

Terkait

Catatan

  • Asumsi: instance homogen, trafik seragam, satu load balancer yang sendiri tidak gagal.
  • Ambang health check (5 detik, 3 gagal) adalah contoh yang umum, bukan nilai universal. Sesuaikan dengan toleransi kegagalan dan beban.
  • Yang tidak dibahas: load balancing global antar region, consistent hashing untuk partisi data (M07), dan service mesh.
  • Terakhir ditinjau: 26 Oktober 2026.

Isi · System Design