Zero-Downtime Deployment
Teknik merilis tanpa menghentikan layanan: multiple instance, health check, graceful shutdown, connection draining, dan reload bertahap.
Zero-downtime berarti pengguna tidak merasakan layanan berhenti saat deploy. Ini membutuhkan kombinasi arsitektur, health check, dan perilaku aplikasi yang benar.
Prasyarat
- Minimal dua instance aplikasi.
- Load balancer/reverse proxy.
- Health check (readiness).
- Graceful shutdown.
- Migrasi database yang kompatibel.
- Proses deploy bertahap.
Alur rolling tanpa downtime
1. Instance baru dinyalakan
2. Health check lulus
3. Proxy mulai mengirim trafik
4. Instance lama berhenti menerima koneksi baru
5. Instance lama menyelesaikan request aktif
6. Instance lama dimatikanHealth check dan readiness
Reverse proxy hanya boleh mengirim trafik ke instance yang siap.
upstream app_backend {
server 10.10.10.11:3000 max_fails=3 fail_timeout=10s;
server 10.10.10.12:3000 max_fails=3 fail_timeout=10s;
}Dengan health check aktif, instance yang gagal dikeluarkan sementara.
Graceful shutdown Node.js
Aplikasi harus berhenti menerima koneksi baru, menyelesaikan request aktif, lalu keluar.
const server = app.listen(3000);
function shutdown(signal) {
console.log(`Menerima ${signal}, mulai shutdown`);
server.close(() => {
console.log('Semua koneksi selesai');
process.exit(0);
});
setTimeout(() => {
console.error('Shutdown timeout, keluar paksa');
process.exit(1);
}, 10000);
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));Dengan PM2, pm2 reload mengirim sinyal dan menunggu proses baru siap.
Docker stop timeout
services:
app:
stop_grace_period: 30sPastikan stop_grace_period lebih besar dari waktu maksimum request.
Connection draining di proxy
Saat instance dikeluarkan dari upstream, request yang sedang berjalan harus diselesaikan.
upstream app_backend {
server 10.10.10.11:3000;
server 10.10.10.12:3000;
keepalive 32;
}
server {
location / {
proxy_pass http://app_backend;
proxy_read_timeout 60s;
proxy_next_upstream error timeout http_502 http_503;
}
}proxy_next_upstream membantu jika satu instance gagal.
Migrasi database tanpa downtime
Gunakan pola expand-contract:
- Tambah kolom/tabel baru (kompatibel dengan kode lama).
- Deploy kode yang menulis ke keduanya.
- Migrasikan data.
- Deploy kode yang hanya memakai struktur baru.
- Hapus struktur lama setelah aman.
Jangan drop kolom saat deploy
Kode lama yang masih berjalan bisa langsung error jika kolom dihapus. Pisahkan migrasi destruktif dari deployment aplikasi.
Blue-green zero downtime
- Green dinyalakan dan diuji.
- Health check green lulus.
- Proxy diarahkan ke green.
- Blue tetap hidup sebagai cadangan.
- Setelah stabil, blue dimatikan.
Rollback hanya dengan mengarahkan proxy kembali ke blue.
Kubernetes readiness
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]Readiness menentukan kapan Pod menerima trafik; preStop memberi waktu draining.
Uji zero downtime
while true; do
curl -s -o /dev/null -w "%{http_code}\n" https://app.example.com/health
sleep 0.5
doneJalankan saat deploy. Jika muncul 502/503, ada celah downtime.
Checklist
- Minimal dua instance.
- Health check tersedia.
- Graceful shutdown diimplementasikan.
- Stop timeout cukup.
- Proxy mendukung draining.
- Migrasi backward compatible.
- Rollback tersedia.
- Deploy diuji dengan traffic.
Ringkasan
- Zero-downtime membutuhkan lebih dari sekadar dua container.
- Health check, graceful shutdown, dan draining adalah kunci.
- Migrasi database harus kompatibel dengan versi lama dan baru.
- Uji dengan traffic nyata, bukan hanya asumsi.
Selanjutnya
Siapkan runbook di Production Troubleshooting.