Episode ini membahas ketahanan layanan: passive dan active health checks, retry policy, pola circuit breaker dengan state open, closed, dan half-open, serta high availability dengan banyak instance Caddy dan load balancer eksternal.

Backend akan gagal. Server restart, proses hang, memory penuh — itu bagian dari kehidupan produksi. Pertanyaannya bukan apakah kegagalan terjadi, tapi bagaimana sistem kalian meresponsnya. Episode 16 membahas mekanisme failover dan circuit breaking di Caddy.
Kalian akan belajar dua jenis health check (pasif dan aktif), kebijakan retry yang aman, dan pola circuit breaker yang mencegah request membebani backend yang sedang sakit. Terakhir, kita lihat bagaimana menyusun high availability dengan banyak instance Caddy.
Tujuan akhir: ketika satu komponen mati, pengguna tidak merasakan apa-apa.
Passive health check tidak mem-probe backend. Sebaliknya, Caddy menilai dari respons request yang sebenarnya:
app.example.com {
reverse_proxy {
to localhost:8080 localhost:8081 localhost:8082
max_fails 2
fail_duration 15s
}
}max_fails 2 — dua kegagalan berturut-turut menandai backend tidak sehat.fail_duration 15s — jendela waktu di mana kegagalan dihitung.Backend yang gagal dikeluarkan dari pool secara otomatis dan dicoba kembali setelah beberapa saat. Ini lapisan pertahanan pertama yang ringan.
Backend yang dikeluarkan akan dimasukkan kembali setelah periode tertentu. Caddy menguji ulang backend tersebut dengan request nyata — jika berhasil, backend kembali ke pool. Tidak ada intervensi manual.
Active health check mem-probe backend secara berkala, bahkan tanpa request dari pengguna:
app.example.com {
reverse_proxy {
to localhost:8080 localhost:8081
health_uri /healthz
health_interval 10s
health_timeout 5s
health_fails 3
health_passes 2
health_expected_status 200
}
}Opsi lengkap:
health_uri /healthz — endpoint yang diprobed.health_interval 10s — interval probe.health_timeout 5s — batas waktu respons probe.health_fails 3 — tiga probe gagal berturut-turut = tidak sehat.health_passes 2 — dua probe sukses berturut-turut = sehat kembali.health_expected_status 200 — status code yang dianggap sukses.health_expected_status 200 memastikan probe dianggap sukses hanya jika backend mengembalikan 200 — bukan sekadar koneksi terbuka.
Endpoint health yang baik harus merefleksikan kesehatan aplikasi, bukan hanya proses. Sebuah aplikasi bisa hidup tapi tidak bisa memproses request (misalnya database putus). Pastikan /healthz di aplikasi memeriksa dependency penting.
Caddy bisa mengulang request ke backend lain saat backend pertama gagal:
app.example.com {
reverse_proxy {
to localhost:8080 localhost:8081
try_duration 10s
try_interval 250ms
}
}try_duration 10s memberi Caddy waktu 10 detik untuk mencoba backend lain; try_interval 250ms mengatur jeda antar percobaan.
Retry otomatis sebaiknya dibatasi untuk request idempotent — yang aman diulang tanpa efek ganda:
Caddy secara default mengulang request yang dianggap idempotent atau yang sudah dikirim sebagian. Untuk POST yang sensitif, lebih baik biarkan gagal daripada membuat duplikat.
Circuit breaker melindungi backend yang sedang sakit dari banjir request:
Di Caddy, perilaku ini muncul dari kombinasi health check dan batas kegagalan:
app.example.com {
reverse_proxy {
to localhost:8080 localhost:8081
max_fails 1
fail_duration 10s
try_duration 5s
}
}Satu kegagalan langsung menandai backend, request diarahkan ke backend lain, dan backend yang gagal punya waktu pulih — esensi circuit breaking tanpa plugin tambahan.
Ketika semua backend gagal, berikan respons yang jelas:
app.example.com {
reverse_proxy {
to localhost:8080 localhost:8081
}
handle_errors {
@down {
expression {http_error.status_code} >= 502
}
handle @down {
respond "Layanan sedang dalam perawatan" 503
}
}
}expression {http_error.status_code} >= 502 menangkap error gateway dan menampilkan halaman maintenance — pengguna mendapat pesan jelas, bukan layar putih.## High Availability Setup
Satu instance Caddy adalah single point of failure. Untuk ketersediaan tinggi:
Kombinasi dengan keepalived + VRRP untuk virtual IP, atau DNS-based failover, memastikan traffic tetap mengalir saat satu instance mati.
Sertifikat ACME harus dibagi antar instance. Tanpa storage bersama, setiap instance meminta sertifikat sendiri dan renewal bisa bentrok. Opsi:
Episode 16 membangun ketahanan layanan: passive health check dengan max_fails, active health check dengan health_uri dan ambang gagal/sukses, retry policy yang aman untuk method idempotent, pola circuit breaker, dan high availability dengan banyak instance serta storage bersama.
Inti yang harus dibawa pulang:
health_expected_status 200 memastikan probe menilai kesehatan aplikasi.Di episode 17 selanjutnya kita masuk ke basic authentication — directive basicauth, hashing password dengan caddy hash-password, melindungi seluruh situs atau path tertentu, beberapa user, dan use case seperti admin panel serta staging environment. Keamanan dasar menanti.