Passive Health Check #
Memantau kesehatan server backend (upstream) secara berkala menggunakan metode pengujian aktif (active health check) memang terbukti efektif untuk menyaring server-server yang mati sebelum mereka menerima lalu lintas pengguna. Namun, di lingkungan produksi yang dinamis dan berskala besar, pemantauan aktif saja tidaklah cukup. Terdapat berbagai jenis kegagalan yang hanya terjadi ketika sistem sedang menangani beban kerja nyata dari pengguna asli—seperti kegagalan koneksi database di tengah jalan, kebocoran memori mendadak yang melambatkan pemrosesan kueri, atau deadlock pada thread pemrosesan aplikasi. Di sinilah Passive Health Check berperan penting. Kita akan membahas cara kerja pemantauan pasif di Caddy, rincian seluruh parameter konfigurasi pendeteksi kegagalan (termasuk status HTTP dan latensi), integrasi Circuit Breaker bawaan, sinergi dengan retry logic guna mencapai toleransi kesalahan maksimal, serta perbandingan taktis antara pendekatan aktif dan pasif untuk memastikan keandalan tingkat tinggi pada infrastruktur kita.
Cara Kerja Passive Health Check #
Mekanisme Passive Health Check bekerja berdasarkan prinsip observasi lalu lintas nyata. Berbeda dengan active health check yang mengirimkan paket uji coba (probe) buatan secara berkala, pemantauan pasif tidak menghasilkan lalu lintas tambahan sama sekali di jaringan kita. Caddy bertindak sebagai pengamat pasif yang memantau setiap respons yang dikembalikan oleh server backend ke pengguna.
Setiap kali pengguna mengirimkan permintaan HTTP, Caddy meneruskan permintaan tersebut ke salah satu server backend yang dipilih oleh kebijakan penyeimbang beban (load balancer policy). Selama proses transmisi dan pemrosesan ini berlangsung, Caddy memantau status koneksi socket TCP, jabat tangan SSL/TLS, kecepatan respons backend, hingga kode status HTTP yang dikembalikan.
Siklus Deteksi dan Pemulihan (Recovery) #
Ketika terjadi kegagalan pada backend, Caddy mencatat insiden tersebut secara internal di memori. Alur kerja deteksi pasif ini mengikuti siklus berikut:
- Pemantauan Kinerja Riil: Caddy meneruskan permintaan dari pengunjung situs ke server backend.
- Pencatatan Kegagalan (Failure Tracking): Jika backend gagal merespons (misalnya mengalami pemutusan koneksi TCP secara sepihak atau mengembalikan kode kesalahan 503), Caddy menaikkan hitungan kegagalan (failure counter) untuk backend tersebut.
- Aktivasi Batas Batasan (Threshold Activation): Jika jumlah kegagalan melebihi batas aman yang kita tentukan (
max_fails) dalam jendela waktu tertentu (fail_duration), Caddy segera menandai backend tersebut sebagai tidak sehat (unhealthy). - Isolasi Backend: Caddy mengeluarkan backend yang bermasalah dari daftar rotasi aktif penyeimbang beban. Selama durasi
fail_durationyang ditentukan, Caddy tidak akan mengirimkan permintaan baru dari pengguna ke server tersebut. - Uji Coba Pemulihan (Trial Recovery): Setelah waktu isolasi
fail_durationhabis, Caddy secara pasif memberikan kesempatan bagi backend tersebut untuk membuktikan kelayakannya kembali. Ketika ada permintaan masuk berikutnya, Caddy akan mencoba mengarahkannya ke backend tersebut. Jika responsnya sukses, hitungan kegagalan dihapus dan backend dinyatakan sehat kembali. Namun, jika responsnya tetap gagal, backend langsung diisolasi kembali untuk durasifail_durationberikutnya.
Representasi Alur Kerja Pemantauan Pasif #
Untuk memberikan gambaran yang lebih jelas, mari kita perhatikan diagram alur bagaimana Caddy menangani request pengguna dan mencatat kegagalan secara pasif pada klaster upstream:
flowchart TD
User["1. Pengunjung Kirim Request"] --> Caddy{"2. Caddy Gateway"}
Caddy -->|"Pilih Upstream"| Backend1["Server Backend 1 (Status: Healthy)"]
Caddy -->|"Pilih Upstream"| Backend2["Server Backend 2 (Status: Unhealthy)"]
subgraph Backend_Evaluation["Evaluasi Pasif Real-Time"]
Backend1 -->|"Kembalikan 200 OK"| CheckSuccess{"Apakah Sukses?"}
CheckSuccess -- "Ya" --> ReturnUser1["Kirim Balasan ke Pengunjung"]
CheckSuccess -- "Tidak (Gagal)" --> IncrementFail1["Naikkan Fail Counter"]
Backend2 -.->|"Menerima Request Uji Coba Pasca Isolasi"| CheckRecover{"Apakah Sukses?"}
CheckRecover -- "Ya" --> ResetFail["Hapus Fail Counter & Status: Healthy"]
CheckRecover -- "Tidak" --> ReIsolate["Isolasi Kembali untuk Durasi fail_duration"]
end
style Caddy stroke:#0288d1,stroke-width:2px
style Backend1 stroke:#43a047,stroke-width:2px
style Backend2 stroke:#e53935,stroke-dasharray:5,5Parameter Konfigurasi Passive Health Check #
Dalam konfigurasi Caddyfile, pemantauan pasif dikonfigurasi langsung di dalam blok reverse_proxy. Parameter-parameter ini memungkinkan kita untuk menyesuaikan sensitivitas deteksi dan durasi pemulihan server backend:
# Contoh konfigurasi dasar passive health check
example.com {
reverse_proxy backend-1:3000 backend-2:3000 {
# Mengaktifkan pemantauan pasif dengan durasi isolasi 30 detik
fail_duration 30s
# Toleransi maksimal kegagalan sebelum diisolasi
max_fails 3
# Kriteria tambahan kode status HTTP yang dianggap sebagai kegagalan
unhealthy_status 500 502 503 504
# Kriteria tambahan latensi respons yang dianggap sebagai kegagalan
unhealthy_latency 5s
# Batas maksimal request konkuren per upstream
unhealthy_request_count 50
}
}
Berikut adalah penjelasan mendalam mengenai masing-masing subdirektif yang kita gunakan di atas:
1. fail_duration
#
Subdirektif fail_duration adalah parameter paling penting dalam konfigurasi pemantauan pasif Caddy. Secara bawaan (default), nilai fail_duration adalah 0 (nol), yang berarti fitur Passive Health Check dinonaktifkan secara total.
Saat kita mengatur fail_duration ke nilai durasi waktu yang valid (misalnya 10s, 30s, atau 5m), kita menginstruksikan Caddy untuk mengaktifkan pelacakan kegagalan dan mengingat status kegagalan setiap backend selama durasi tersebut. Parameter ini memiliki peran ganda:
- Jendela Waktu Pelacakan (Sliding Window): Caddy memantau jumlah kegagalan yang terjadi dalam rentang waktu ini. Jika kita menetapkan
fail_duration 30s, maka Caddy hanya menghitung akumulasi kegagalan yang terjadi dalam 30 detik terakhir. Kegagalan yang terjadi lebih lama dari 30 detik akan kedaluwarsa dan dihapus dari hitungan. - Waktu Isolasi (Penalty Duration): Ketika sebuah backend melampaui batas maksimal kegagalan (
max_fails), backend tersebut akan diisolasi dari rotasi penyeimbang beban selama durasi ini.
2. max_fails
#
Subdirektif max_fails menentukan jumlah maksimal kegagalan yang diizinkan terjadi pada satu backend dalam kurun waktu fail_duration sebelum backend tersebut dinyatakan tidak sehat (unhealthy). Nilai bawaan untuk parameter ini adalah 1.
- Desain Sensitif (max_fails 1): Cocok untuk sistem kritis dengan tingkat redundansi backend yang tinggi. Satu kegagalan saja pada server backend akan langsung memicu Caddy untuk mengisolasinya dari jaringan, sehingga meminimalkan jumlah pengguna yang terkena dampak kegagalan.
- Desain Toleran (max_fails 3 atau lebih): Berguna jika koneksi jaringan antara Caddy dan server backend sering kali mengalami gangguan kecil yang bersifat sementara (network flappings). Dengan menetapkan nilai lebih dari satu, kita menghindari isolasi backend secara terburu-buru akibat gangguan jaringan sesaat.
3. unhealthy_status
#
Secara bawaan, Caddy menganggap sebuah request mengalami kegagalan hanya jika terjadi masalah pada level transport (seperti koneksi ditolak atau timeout soket). Namun, aplikasi web kita sering kali tetap mengembalikan respons HTTP valid namun dengan kode status kesalahan seperti 500 Internal Server Error atau 503 Service Unavailable.
Dengan menambahkan unhealthy_status, kita memperluas cakupan deteksi kegagalan hingga ke tingkat aplikasi. Kita dapat mendaftarkan kode status HTTP tertentu atau menggunakan format kelas status (seperti 5xx) untuk mendeteksi kegagalan aplikasi:
# ANTI-PATTERN: Mengabaikan kode status kesalahan aplikasi
reverse_proxy backend-1:3000 backend-2:3000 {
fail_duration 30s
# Caddy hanya mendeteksi crash OS/jaringan, tapi tetap mengarahkan traffic ke backend
# yang mengalami error database internal dan mengembalikan status 500.
}
# BENAR: Menangkap kegagalan internal server
reverse_proxy backend-1:3000 backend-2:3000 {
fail_duration 30s
max_fails 3
unhealthy_status 500-504
}
[!WARNING] Jangan pernah memasukkan kelas kode status
4xx(seperti400 Bad Requestatau404 Not Found) ke dalam konfigurasiunhealthy_status. Kode status4xxmewakili kesalahan yang dilakukan oleh klien (pengguna akhir), bukan kegagalan server backend. Jika kita memasukkan4xx, maka tindakan pengguna yang tidak sengaja mengakses halaman yang tidak ada (404) dapat menyebabkan server backend sehat kita diisolasi secara tidak adil.
4. unhealthy_latency
#
Ketika server backend kita mengalami kelebihan beban (overloaded), salah satu gejala pertamanya adalah melambatnya waktu respons (response time). Server tidak langsung mati atau mengembalikan error, melainkan memproses request secara sangat lambat. Hal ini dapat menyebabkan penumpukan antrean koneksi di sisi Caddy, yang pada akhir-akhirnya menurunkan kinerja seluruh gerbang aplikasi.
Subdirektif unhealthy_latency memungkinkan kita mendeteksi server backend yang melambat tersebut. Jika respons dari sebuah backend membutuhkan waktu lebih lama dari nilai durasi yang ditentukan (misalnya unhealthy_latency 5s), Caddy akan menghitung request tersebut sebagai satu kegagalan.
5. unhealthy_request_count
#
Parameter unhealthy_request_count menetapkan batas maksimal jumlah koneksi konkuren (permintaan yang sedang diproses secara bersamaan) untuk setiap server backend. Jika sebuah server sedang memproses permintaan dalam jumlah yang sama atau lebih besar dari batas ini, Caddy akan menganggap server tersebut sudah penuh (saturated) dan menandainya sebagai tidak sehat untuk sementara waktu agar tidak dikirimi beban tambahan. Hal ini sangat membantu untuk mencegah runtuhnya backend akibat fenomena Thundering Herd.
Mekanisme Deteksi Kegagalan Event-Driven #
Untuk memahami bagaimana Caddy secara cerdas mengidentifikasi kegagalan secara pasif, kita harus melihat bagaimana Caddy memproses koneksi pada level sistem operasi dan jaringan. Caddy menggunakan model penanganan kegagalan yang bersifat event-driven berdasarkan kejadian nyata di tumpukan (stack) protokol jaringan:
+-------------------------------------------------------------------------+
| Klasifikasi Kegagalan Pasif di Caddy |
+-------------------------------------------------------------------------+
| 1. Kegagalan Jaringan & Transport (Otomatis Dideteksi): |
| * TCP Connection Refused (Backend mati / Port tertutup) |
| * TCP Connection Timeout (Firewall memblokir paket / Server sibuk) |
| * TLS Handshake Timeout (Negosiasi enkripsi macet) |
| * Read/Write Timeout (Koneksi terputus di tengah transmisi data) |
| |
| 2. Kegagalan Aplikasi (Opsional via Konfigurasi): |
| * Kriteria HTTP Status (Misal: 500, 502, 503, 504) |
| * Kriteria Latensi Respons (Respons melebihi batas waktu toleransi) |
+-------------------------------------------------------------------------+
Deteksi Tingkat Transport #
Ketika Caddy mencoba meneruskan permintaan pengguna ke server backend, Caddy melakukan panggilan sistem (system call) ke kernel sistem operasi untuk membuka soket koneksi baru. Caddy mengamati beberapa jenis kegagalan transport berikut:
- TCP Connection Refused (RST Packet): Jika port aplikasi backend mati atau proses backend tidak berjalan, sistem operasi tujuan akan mengembalikan paket
RST(Reset) ke Caddy. Caddy secara instan mendeteksi ini sebagai kegagalan transport. - TCP Connection Timeout: Jika server backend mati total atau terjadi kendala perutean (routing) di jaringan, paket
SYNyang dikirim Caddy tidak akan pernah mendapat balasan. Koneksi akan menggantung hingga batas waktu dial berakhir (dial timeout), yang langsung dicatat oleh Caddy sebagai kegagalan. - TLS Handshake Failures: Jika backend dikonfigurasi menggunakan HTTPS dan terjadi kegagalan negosiasi sertifikat TLS—seperti sertifikat kedaluwarsa, tidak dipercaya, atau jabat tangan yang menggantung melewati batas waktu—Caddy menganggap backend tersebut gagal beroperasi.
Deteksi Tingkat Aplikasi #
Setelah koneksi TCP dan TLS berhasil terbentuk, Caddy mengirimkan payload HTTP request dan menunggu respons. Di sinilah konfigurasi unhealthy_status and unhealthy_latency dievaluasi:
- Evaluasi Kode Status: Begitu header respons HTTP diterima dari backend, Caddy mencocokkan kode statusnya dengan daftar pada
unhealthy_status. Jika ada kecocokan, Caddy menaikkan indikator kegagalan. - Evaluasi Batas Waktu Latensi: Caddy menghitung waktu sejak byte pertama request dikirim hingga byte pertama respons diterima. Jika durasi ini melampaui batas
unhealthy_latency, Caddy menghentikan proses tunggu (atau membiarkannya selesai tergantung konfigurasi transport) dan mencatat satu kegagalan.
Pola Circuit Breaker Terintegrasi #
Circuit Breaker (Pemutus Sirkuit) adalah pola desain arsitektur perangkat lunak yang digunakan untuk mencegah kegagalan lokal pada satu layanan merambat ke seluruh sistem. Caddy secara elegan mengintegrasikan pola Circuit Breaker ini secara langsung di dalam modul pemantauan pasifnya.
Transisi Status Circuit Breaker di Caddy #
Circuit Breaker di Caddy beroperasi dalam mesin keadaan (state machine) tiga status: Closed, Open, dan Half-Open.
stateDiagram-v2
[*] --> Closed: Mulai / Upstream Sehat
Closed --> Open: "Akumulasi Kegagalan >= max_fails\n(dalam rentang fail_duration)"
note right of Closed
Status NORMAL.
Lalu lintas dikirim ke semua
backend. Kegagalan dilacak.
end note
Open --> HalfOpen: "Durasi Waktu fail_duration\ntelah Berakhir"
note left of Open
Status ERROR / ISOLASI.
Backend bermasalah dilewati.
Tidak ada lalu lintas ke sana.
end note
HalfOpen --> Closed: "Request Pertama Sukses\n(Status Kembali Sehat)"
HalfOpen --> Open: "Request Pertama Gagal\n(Isolasi Ulang)"
note right of HalfOpen
Status UJI COBA.
Caddy mengirimkan request
pengguna berikutnya ke backend ini.
end noteBerikut adalah penjelasan rincinya mengenai setiap transisi status pada diagram di atas:
1. Status CLOSED (Keadaan Normal) #
Pada keadaan ini, “sirkuit” tertutup, artinya arus lalu lintas data mengalir secara lancar dari Caddy ke seluruh server backend. Caddy secara aktif memantau respons backend dan mencatat kegagalan. Selama jumlah kegagalan berada di bawah ambang batas max_fails, status tetap berada pada status CLOSED.
2. Status OPEN (Keadaan Terputus / Isolasi) #
Ketika jumlah kegagalan pada suatu backend mencapai atau melampaui max_fails dalam jendela waktu fail_duration, sirkuit beralih ke status OPEN.
Dalam keadaan ini, Caddy “memutus” aliran ke backend tersebut. Caddy segera mengisolasi server backend tersebut dan tidak akan mengarahkan request pengguna ke sana. Langkah ini memberikan waktu bernapas bagi server backend kita yang sedang kewalahan untuk melakukan pemulihan (misalnya melakukan restart otomatis, membersihkan memori, atau menyelesaikan antrean kueri database yang menumpuk) tanpa terus-menerus dihujani request baru.
3. Status HALF-OPEN (Keadaan Uji Coba) #
Setelah durasi isolasi fail_duration terlewati, sirkuit secara otomatis beralih ke status HALF-OPEN.
Pada status ini, Caddy bertindak secara hati-hati. Caddy tidak langsung menandai backend tersebut sebagai sehat sepenuhnya. Ketika ada request berikutnya dari pengguna masuk ke Caddy, Caddy akan mencoba menguji backend tersebut dengan mengirimkan request tersebut ke sana.
- Jika request uji coba tersebut berhasil, sirkuit kembali ke status CLOSED (sehat sepenuhnya), menghapus seluruh catatan kegagalan sebelumnya, dan memulihkan backend ke rotasi penuh.
- Jika request uji coba tersebut gagal, sirkuit langsung kembali ke status OPEN (terputus), dan Caddy kembali mengisolasi backend tersebut untuk durasi
fail_durationyang baru.
Sinergi dengan Retry Logic #
Salah satu kelemahan utama dari pemantauan pasif yang berdiri sendiri adalah adanya efek samping pada pengguna akhir. Karena Caddy membutuhkan lalu lintas nyata untuk mendeteksi kegagalan, maka pengguna yang mengirimkan request saat backend pertama kali mati akan menerima pesan kesalahan (seperti 502 Bad Gateway atau 504 Gateway Timeout) sebelum Caddy menyadari backend tersebut mati dan mengisolasinya.
Untuk mengatasi kelemahan ini, kita wajib mengombinasikan Passive Health Check dengan Retry Logic menggunakan direktif lb_try_duration dan lb_try_interval.
Mekanisme Kerja Sinergi Pasif dan Retry #
Ketika kita mengaktifkan retry, Caddy akan melakukan pengalihan lalu lintas secara transparan di latar belakang ketika mendeteksi kegagalan koneksi:
- Request Datang: Pengguna mengirimkan permintaan ke Caddy.
- Percobaan Pertama: Caddy mengarahkan request ke
backend-1yang ternyata baru saja mati. - Deteksi Kegagalan: Caddy mendeteksi koneksi ke
backend-1ditolak (Connection Refused). - Pencatatan Pasif: Passive health check mencatat 1 kegagalan untuk
backend-1. - Aktivasi Retry: Caddy tidak langsung mengembalikan error ke pengguna. Caddy melihat bahwa
lb_try_durationtelah dikonfigurasi. - Percobaan Kedua (Retry): Caddy segera mengalihkan request yang sama ke
backend-2yang sehat secara instan. - Keberhasilan Transparan:
backend-2merespons dengan sukses. Pengguna menerima halaman web secara normal tanpa menyadari bahwa sempat terjadi kegagalan di backend utama.
Mari kita perhatikan visualisasi interaksi ini melalui diagram urutan (sequence diagram) berikut:
sequenceDiagram
participant Klien as Pengunjung Web
participant Caddy as Caddy Gateway
participant B1 as Backend 1 (Baru Saja Mati)
participant B2 as Backend 2 (Sehat)
Klien->>Caddy: Kirim HTTP Request
Caddy->>B1: Teruskan Request (Percobaan Pertama)
Note over B1: B1 mengalami crash internal
B1-->>Caddy: Connection Refused / Error
Note over Caddy: Caddy mencatat kegagalan pasif untuk B1 (+1 Fail Counter)
Note over Caddy: Caddy melakukan Retry karena lb_try_duration aktif
Caddy->>B2: Teruskan Request ke Backend Alternatif
B2-->>Caddy: HTTP/1.1 200 OK (Sukses)
Caddy-->>Klien: Kembalikan Respons Sukses
Note over Klien,B2: Pengunjung tidak merasakan error sama sekali!Konfigurasi Produksi Sinergi Pasif dan Retry #
Berikut adalah contoh konfigurasi Caddyfile yang menggabungkan pemantauan pasif, pembatasan latensi, dan logika retry secara optimal untuk lingkungan produksi:
# Konfigurasi ketahanan tingkat tinggi di produksi
api.example.com {
reverse_proxy backend-1:8080 backend-2:8080 backend-3:8080 {
# ═══ Pemantauan Pasif (Circuit Breaker) ═══
# Aktifkan pelacakan pasif dengan isolasi 30 detik
fail_duration 30s
# Isolasi backend jika terjadi 2 kegagalan dalam window 30s
max_fails 2
# Anggap status 502, 503, dan 504 sebagai kegagalan aplikasi
unhealthy_status 502 503 504
# Anggap respons yang lebih lambat dari 3 detik sebagai kegagalan
unhealthy_latency 3s
# ═══ Logika Retry (Toleransi Kesalahan Transparan) ═══
# Caddy akan terus mencoba backend lain selama maksimal 5 detik
lb_try_duration 5s
# Berikan jeda 200ms sebelum mencoba backend berikutnya
lb_try_interval 200ms
# Konfigurasi transport http untuk mempercepat deteksi kegagalan
transport http {
dial_timeout 2s
response_header_timeout 5s
}
}
}
Kombinasi Terbaik: Active + Passive Health Check #
Untuk membangun infrastruktur penyeimbang beban yang benar-benar andal (High Availability), kita tidak boleh memilih salah satu antara pemantauan aktif atau pasif. Kita harus menggabungkan keduanya untuk saling melengkapi.
Tabel Perbandingan Perilaku Pemantauan #
| Karakteristik | Active Health Check | Passive Health Check |
|---|---|---|
| Metode Kerja | Mengirim probe periodik di latar belakang | Mengamati lalu lintas nyata pengguna |
| Dampak Jaringan | Menambah sedikit lalu lintas data buatan | Nol (tidak ada overhead jaringan) |
| Kebutuhan Backend | Membutuhkan endpoint khusus (misal /healthz) | Tidak membutuhkan endpoint khusus |
| Waktu Deteksi | Cepat, dideteksi sebelum traffic pengguna tiba | Reaktif, bergantung pada adanya traffic masuk |
| Penanganan Error | Sangat baik untuk mendeteksi kematian total backend | Sangat baik untuk mendeteksi anomali saat beban tinggi |
Arsitektur Pertahanan Berlapis (Unified Checking) #
Ketika kita menggunakan kedua metode ini secara bersamaan, kita menciptakan sistem pertahanan berlapis:
- Lapisan Pertama (Active Check - Pencegahan): Setiap 10 detik, poller Caddy memeriksa kesehatan semua backend. Jika salah satu server backend mati saat dini hari (ketika tidak ada lalu lintas pengguna), active health check akan mendeteksinya dan langsung mengisolasinya sebelum pengguna pertama terbangun dan mengakses aplikasi kita.
- Lapisan Kedua (Passive Check - Perlindungan Real-Time): Jika sebuah server backend tiba-tiba mengalami kehabisan memori RAM (Out Of Memory) atau kueri database terkunci (database lock) tepat setelah lolos dari pemindaian active check ke-5, request pengguna berikutnya yang mengalami kegagalan akan langsung ditangkap oleh pemantau pasif. Caddy segera mengisolasi server tersebut tanpa menunggu jadwal pemindaian active check berikutnya tiba.
Berikut adalah konfigurasi lengkap pertahanan berlapis pada Caddyfile:
# Konfigurasi pertahanan berlapis untuk aplikasi kritis
app.example.com {
reverse_proxy backend-1:8080 backend-2:8080 backend-3:8080 {
# Gunakan kebijakan least_conn agar beban terbagi secara adil
lb_policy least_conn
# ─── LAPISAN 1: Active Health Check (Pemantauan Latar Belakang) ───
health_uri /healthz
health_interval 15s
health_timeout 3s
# Membutuhkan token otentikasi agar endpoint aman
health_headers {
Authorization "Bearer token-keamanan-internal-caddy"
}
# ─── LAPISAN 2: Passive Health Check (Pemantauan Lalu Lintas Nyata) ───
fail_duration 60s
max_fails 3
unhealthy_status 500 502 503 504
unhealthy_latency 4s
# ─── LAPISAN 3: Logika Retry (Penyelamat Request Pengguna) ───
lb_try_duration 8s
lb_try_interval 250ms
# Konfigurasi transport level agar timeout terkelola dengan baik
transport http {
dial_timeout 3s
response_header_timeout 10s
}
}
}
Konfigurasi untuk Berbagai Skenario #
Setiap aplikasi memiliki karakteristik dan toleransi kesalahan yang berbeda. Kita harus menyesuaikan parameter pemantauan pasif berdasarkan kebutuhan skenario di lapangan:
1. Skenario Layanan Non-Kritis / Toleransi Longgar (Loose Config) #
Untuk layanan internal, dokumentasi statis, atau server pengujian (staging) di mana ketersediaan 100% tidak terlalu dituntut dan kita ingin menghemat sumber daya CPU agar tidak terlalu sering melakukan evaluasi kegagalan:
# Konfigurasi toleransi longgar untuk service non-kritis
staging.example.com {
reverse_proxy staging-1:3000 staging-2:3000 {
# Waktu isolasi cukup singkat
fail_duration 15s
# Baru diisolasi jika terjadi kegagalan yang cukup masif
max_fails 5
# Hanya mendeteksi kegagalan jaringan dasar, abaikan latensi lambat
}
}
2. Skenario Layanan Kritis / Toleransi Sangat Ketat (Strict Config) #
Untuk aplikasi perbankan, gerbang pembayaran (payment gateway), API transaksi, atau layanan e-commerce di mana satu kesalahan saja dapat mengganggu jalannya bisnis dan kenyamanan pengguna:
# Konfigurasi super ketat untuk transaksi finansial
checkout.example.com {
reverse_proxy prod-1:9000 prod-2:9000 prod-3:9000 {
lb_policy least_conn
# Isolasi yang cukup lama untuk memastikan backend benar-benar pulih
fail_duration 2m
# Langsung isolasi backend begitu terjadi 1 kali kegagalan!
max_fails 1
# Sangat sensitif terhadap error internal server
unhealthy_status 500 502 503 504
# Sangat sensitif terhadap kelambatan sistem
unhealthy_latency 1.5s
# Retry yang sangat agresif untuk menyelamatkan request pengguna
lb_try_duration 4s
lb_try_interval 100ms
transport http {
dial_timeout 1s
response_header_timeout 2s
}
}
}
Logging, Observability, dan Troubleshooting #
Untuk memastikan pemantauan pasif kita bekerja dengan benar dan memantau kesehatan klaster backend secara transparan, kita harus mengonfigurasi pencatatan log (logging) Caddy secara memadai dan mempelajari cara menganalisis kejadian kegagalan dari berkas log tersebut.
Mengonfigurasi Log Akses Caddy #
Kita harus mengaktifkan penulisan log berformat JSON di tingkat global agar data akses dan penyeimbangan beban dapat dibaca dengan mudah oleh aplikasi pengumpul log (seperti ElasticSearch, Loki, atau Datadog):
# Konfigurasi log global di Caddyfile
{
log {
output file /var/log/caddy/system.log {
roll_size 100mib
roll_keep 10
}
format json
}
}
api.example.com {
log {
output file /var/log/caddy/api_access.log
format json
}
reverse_proxy backend-1:8080 backend-2:8080 {
fail_duration 30s
max_fails 2
}
}
Menganalisis Log Peristiwa Pemantauan Pasif #
Ketika Caddy mendeteksi kegagalan dan memutuskan untuk mengisolasi server backend, Caddy akan menulis log sistem dengan tingkat keamanan INFO.
Contoh Log: Upstream Diisolasi (Unhealthy) #
Berikut adalah contoh struktur data JSON log ketika sebuah backend ditandai tidak tersedia karena melampaui max_fails:
{
"level": "info",
"ts": 1781682415.123456,
"logger": "http.handlers.reverse_proxy",
"msg": "upstream is now unavailable",
"upstream": "backend-1:8080",
"total_fails": 2
}
Contoh Log: Upstream Sehat Kembali (Healthy) #
Ketika durasi fail_duration habis dan backend tersebut berhasil memproses request uji coba pertama pada status HALF-OPEN, Caddy akan menulis log pemulihan berikut:
{
"level": "info",
"ts": 1781682445.654321,
"logger": "http.handlers.reverse_proxy",
"msg": "upstream is now available",
"upstream": "backend-1:8080"
}
Perintah Terminal untuk Analisis Cepat (CLI Debugging) #
Sebagai administrator sistem, kita dapat memantau kejadian ini secara langsung di server menggunakan perintah Unix standard.
1. Filter Log Real-Time untuk Kejadian Kesehatan Backend #
Jalankan perintah berikut untuk mengamati perubahan status backend secara langsung di terminal kita:
# Memantau perubahan status upstream secara real-time dari log sistem Caddy
tail -f /var/log/caddy/system.log | grep -E --line-buffered "upstream is now"
# Output Contoh:
# {"level":"info","ts":1781682415.123,"logger":"http.handlers.reverse_proxy","msg":"upstream is now unavailable","upstream":"10.0.1.15:8080","total_fails":2}
# {"level":"info","ts":1781682445.654,"logger":"http.handlers.reverse_proxy","msg":"upstream is now available","upstream":"10.0.1.15:8080"}
2. Menghitung Rasio Error per Upstream Menggunakan jq dan awk
#
Jika kita ingin menganalisis berkas log akses untuk melihat persentase error yang dihasilkan oleh masing-masing alamat upstream dalam kurun waktu tertentu, jalankan perintah satu baris berikut:
# Ekstrak data upstream_addr dan status code dari log JSON, lalu hitung rasio error-nya
cat /var/log/caddy/api_access.log | jq -r 'select(.upstream_addr != null) | [.upstream_addr, (.status | tostring)] | @tsv' | \
awk -F'\t' '{
total[$1]++
if ($2 >= "500") errors[$1]++
} END {
print "=== LAPORAN RASIO ERROR UPSTREAM ==="
for (addr in total) {
err_rate = (errors[addr] ? errors[addr] : 0) / total[addr] * 100
printf "%s -> Total Request: %d, Error (5xx): %d, Rasio Error: %.2f%%\n", addr, total[addr], (errors[addr] ? errors[addr] : 0), err_rate
}
}'
Perintah di atas akan memberikan output laporan terstruktur seperti berikut:
=== LAPORAN RASIO ERROR UPSTREAM ===
10.0.1.15:8080 -> Total Request: 14205, Error (5xx): 14, Rasio Error: 0.10%
10.0.1.16:8080 -> Total Request: 14198, Error (5xx): 348, Rasio Error: 2.45%
Dengan laporan ini, kita dapat langsung mencurigai bahwa server 10.0.1.16 sedang mengalami masalah stabilitas internal karena memiliki rasio error yang jauh lebih tinggi dibandingkan mitranya.
Checklist Review Implementasi #
Untuk memastikan konfigurasi Passive Health Check kita di produksi berjalan dengan aman dan efisien, pastikan kita mencentang seluruh poin pemeriksaan berikut sebelum melakukan rilis:
KATEGORI 1: KONFIGURASI PARAMETER
□ fail_duration telah diatur ke nilai > 0 (pemantauan pasif tidak akan aktif jika bernilai 0).
□ max_fails telah disesuaikan dengan tingkat redundansi cluster kita (disarankan 2-3 untuk menghindari false alarm).
□ unhealthy_status hanya berisi kode status server (5xx) dan TIDAK memasukkan kode status klien (4xx).
□ unhealthy_latency telah diatur untuk menghindari penumpukan antrean request pada backend yang lambat.
KATEGORI 2: KETAHANAN DAN LOGIKA RETRY
□ lb_try_duration telah diaktifkan untuk memastikan request pengguna dialihkan ke backend lain saat kegagalan pasif terjadi.
□ Nilai lb_try_duration lebih panjang daripada dial_timeout di blok transport.
□ Jeda retry (lb_try_interval) telah diatur secara rasional agar tidak membanjiri backend alternatif.
KATEGORI 3: INTEGRASI PEMANTAUAN
□ Active health check dikonfigurasikan bersama dengan passive health check untuk perlindungan berlapis yang optimal.
□ Format log global telah disetel ke JSON agar mudah dipetakan oleh sistem pengumpul log eksternal.
Ringkasan #
- Definisi Utama: Fitur Passive Health Check mengamati status dan respons dari lalu lintas riil pengguna ke server backend tanpa membuat lalu lintas data buatan di jaringan.
- Aktivasi Fitur: Kita wajib mengatur nilai
fail_durationke angka durasi waktu yang lebih besar dari nol agar fitur pemantauan pasif ini dapat beroperasi.- Pola Circuit Breaker: Caddy secara otomatis menerapkan pola pemutus sirkuit dengan tiga status (Closed, Open, Half-Open) untuk mengisolasi server backend yang bermasalah.
- Deteksi Aplikasi: Gunakan subdirektif
unhealthy_statusdanunhealthy_latencyuntuk menyaring backend yang berjalan lambat atau mengembalikan error internal server.- Sinergi Retry: Gabungkan pemantauan pasif dengan
lb_try_durationagar kegagalan pertama di backend yang rusak dialihkan secara transparan ke backend alternatif tanpa memunculkan error ke sisi pengguna.- Pertahanan Berlapis: Integrasikan pemantauan aktif (proaktif) dan pasif (reaktif) pada saat yang bersamaan untuk menjamin keandalan klaster backend di tingkat produksi.
← Sebelumnya: Active Health Check Berikutnya: Admin Endpoint →