Shutdown
Setelah kita bisa menyalakan server, pertanyaan selanjutnya adalah: bagaimana mematikannya dengan aman?
Dalam lingkungan produksi, server tidak boleh berhenti secara tiba-tiba. Ada permintaan yang sedang diproses, koneksi database yang terbuka, atau task latar belakang yang belum selesai. Mematikan server secara paksa (hard shutdown) dapat menyebabkan:
Response terputus di tengah jalan (client mendapat error)
Data tidak tersimpan dengan benar
State aplikasi menjadi korup
Go menyediakan mekanisme graceful shutdown untuk mengatasi masalah ini.
π Kode Lengkap Bab Ini: Seluruh kode yang dibahas di bab ini tersedia di GitHub:
2.1 Mendengarkan Sinyal dari OS
Langkah pertama adalah mengetahui kapan sistem operasi ingin mematikan aplikasi kita. Di Linux/Unix, proses menerima sinyal seperti:
SIGINTβ dikirim saat user menekanCtrl+CSIGTERMβ dikirim olehkill,systemctl stop, ataudocker stop
Kita bisa mendengarkan sinyal-sinyal ini menggunakan signal.Notify:
shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)Catatan: Channel harus buffered karena paket signal tidak akan memblokir saat mengirim sinyal.
2.2 Menggabungkan Dua Sumber Event dengan select
selectSekarang aplikasi kita memiliki dua sumber event asinkron:
Server error β terjadi jika server gagal berjalan (misal port sudah digunakan)
Shutdown signal β terjadi jika OS meminta aplikasi berhenti
Kita menggunakan select untuk menangani keduanya secara bersamaan:
2.3 Implementasi Graceful Shutdown Lengkap
Berikut implementasi lengkap dengan strategi fallback: jika graceful shutdown gagal, kita paksa tutup dengan server.Close().
2.4 Keterbatasan Graceful Shutdown
Penting untuk memahami bahwa tidak semua skenario bisa ditangani dengan graceful shutdown:
Perbandingan Berbagai Skenario Shutdown:
Skenario
Graceful Shutdown
server.Close()
Data Loss Risk
Listrik mati
β Tidak jalan
β Tidak jalan
π΄ Tinggi
Kill -9 (SIGKILL)
β Tidak jalan
β Tidak jalan
π΄ Tinggi
Ctrl+C (SIGINT)
β Jalan (jika di-handle)
Bisa dipanggil
π’ Rendah
Kill / systemctl stop (SIGTERM)
β Jalan (jika di-handle)
Bisa dipanggil
π’ Rendah
Docker stop (SIGTERM)
β Jalan (jika di-handle)
Bisa dipanggil
π’ Rendah
Pesan penting: Tidak ada kode Go yang bisa berjalan saat listrik mati atau proses di-kill -9. Graceful shutdown hanya melindungi dari shutdown normal yang dikirim melalui sinyal OS.
2.5 Memahami Dua Metode Penutupan Server
Go menyediakan dua metode berbeda untuk menutup server. Pilih berdasarkan kebutuhan:
server.Close() β Penutupan Paksa
server.Close() β Penutupan PaksaMenutup listener dan semua koneksi aktif seketika
Request yang sedang berjalan terputus, client mendapat connection reset
Non-blocking, langsung return
server.Shutdown(ctx) β Penutupan Bertahap
server.Shutdown(ctx) β Penutupan BertahapMenutup listener β tidak menerima request baru
Menunggu semua request yang sedang berjalan selesai
Koneksi idle ditutup dengan normal
Blocking sampai selesai atau timeout
Aspek
server.Close()
server.Shutdown(ctx)
Menutup listener
β Langsung
β Setelah graceful
Koneksi aktif
β Diputus paksa (reset)
β Ditunggu selesai
Request dalam proses
β Terputus, client dapat error
β Diberi waktu selesai
Keep-Alive connections
β Ditutup paksa
β Ditutup setelah idle
HTTP/2 streams
β Diputus
β Ditunggu selesai
Menerima request baru
β Langsung ditolak
β Langsung ditolak
Idle connections
β Diputus paksa
β Ditutup normal
Context support
β Tidak ada timeout
β Bisa pakai timeout
Error return
β
Selalu return error (biasanya http.ErrServerClosed)
β Return error jika timeout atau gagal
Blocking behavior
β Non-blocking, langsung return
β Blocking sampai semua koneksi selesai atau timeout
Use case
Force shutdown, testing, atau saat graceful gagal
Production graceful shutdown
Client experience
π΄ Connection reset / EOF
π’ Mendapat response lengkap
Risk
β οΈ Data loss, corrupted state
β Aman untuk data integrity
Praktik terbaik: Gunakan Shutdown sebagai cara utama, dan simpan Close sebagai fallback jika graceful gagal (seperti pada contoh kode di atas).
Ringkasan Bab 2
Di bab ini kita telah belajar:
Mendengarkan sinyal OS (SIGINT, SIGTERM) menggunakan signal.Notify
Menggabungkan multiple channel events dengan select
Implementasi graceful shutdown dengan server.Shutdown
Fallback mekanisme dengan server.Close
Memahami keterbatasan graceful shutdown pada skenario ekstrem
Pada bab berikutnya, kita akan membahas bagaimana menangani data dalam format JSON β tulang punggung komunikasi API modern.
Last updated