Kelola koneksi
Koneksi real-time pasti putus. Atur reconnect dengan jitter, heartbeat, presence berbasis TTL, perutean koneksi, dan buffer tiap klien yang berbatas.
Pertanyaan
Apa yang harus terjadi saat koneksi putus, klien lambat, atau satu node gateway mati?
Setelah baca ini, kamu bisa merancang siklus hidup koneksi: penyambungan ulang, deteksi koneksi mati, presence, perutean pesan ke node yang tepat, dan batas buffer tiap klien.
Prasyarat dan contoh
Kamu sudah milih kanal real-time (M13.01) dan paham retry serta timeout (M03). Konsep cache dan partisi dari M06 dan M07 membantu buat bagian perutean.
Gateway kamu pegang 100.000 koneksi WebSocket. Saat deploy, node di-restart dan 100.000 klien terputus dalam detik yang sama. Kalau semuanya langsung nyambung ulang, node lain kebanjiran 100.000 handshake plus autentikasi plus sinkronisasi sekaligus, dan bisa ikut tumbang. Itu bukan kegagalan langka. Itu rutinitas deploy.
Mekanisme
Penyambungan ulang. Klien nyambung ulang dengan exponential backoff dan jitter: tunggu acak antara 0 dan min(30 detik, 1 detik × 2^percobaan). Jitter itu yang memecah lonjakan. Tanpa jitter, semua klien mencoba di detik 1, 2, 4, dan seterusnya bersamaan. Server juga boleh menolak dengan sinyal "coba lagi setelah N detik" saat sedang kewalahan.
Heartbeat. Koneksi TCP yang mati diam-diam (HP masuk terowongan, NAT membuang mapping) nggak kasih tahu siapa pun. Kirim ping tiap 25 detik, anggap koneksi mati setelah dua ping tanpa balasan (sekitar 50 detik). Interval harus lebih pendek dari timeout idle proxy, yang sering 60 detik. Hasilnya: server bebas dari koneksi zombi dan klien tahu kapan harus nyambung ulang.
Presence. Status "online" itu data yang cepat basi. Simpan sebagai kunci dengan TTL: tiap
heartbeat memperpanjang presence:{user} selama 60 detik. Kalau heartbeat berhenti, kunci hilang
sendiri tanpa perlu event "putus" yang bisa saja nggak pernah terkirim. Satu pengguna bisa punya
beberapa perangkat, jadi simpan per koneksi dan hitung online jika ada minimal satu yang hidup.
Presence itu perkiraan: tampilkan "terakhir terlihat" alih-alih janji presisi.
Perutean koneksi. Pesan buat user U harus sampai ke node yang memegang koneksi U. Simpan
registri user → node (dengan TTL yang sama seperti presence), atau publikasikan ke saluran
per node. Saat pesan datang: cari node, kirim ke sana, node menulis ke soket. Kalau registri
kosong, pesan tetap disimpan dan dikirim saat klien nyambung lagi (lihat M13.03). Registri bisa
usang, jadi node penerima harus bilang "bukan di sini" dan pengirim jatuh ke jalur simpan.
Buffer tiap klien. Klien lambat (jaringan buruk) membuat antrean kirim di server tumbuh. Kalau tanpa batas: 10.000 klien lambat × 5 MB = 50 GB, dan node mati karena memori. Beri batas keras, misalnya 1.000 pesan atau 1 MB per koneksi, dan putuskan kebijakannya sebelum batas tercapai:
- Putus koneksi. Klien nyambung ulang dan sinkronisasi dari kursor terakhirnya.
- Buang pesan murahan. Buat data yang cuma nilai terakhirnya penting (posisi kursor, indikator mengetik), ganti pesan lama dengan yang baru.
- Jangan buang pesan penting diam-diam. Pesan chat tidak boleh dibuang tanpa jejak. Lebih baik koneksinya diputus supaya klien sadar ada celah dan minta ulang.
Saat rancangan ini gagal
- Reconnect serentak. Tanpa jitter, deploy satu node menghasilkan lonjakan handshake yang menjatuhkan node berikutnya, lalu berantai.
- Presence berbasis event putus. Event "disconnect" hilang saat node crash, jadi pengguna tampak online berjam-jam. TTL menghindarinya.
- Registri koneksi usang. Pesan dikirim ke node yang sudah tidak memegang koneksinya dan dianggap terkirim. Tanpa ack dari klien, itu kehilangan diam-diam.
- Buffer tanpa batas. Satu aplikasi klien yang berhenti membaca bisa menaikkan memori node.
- Heartbeat terlalu rapat. Ping tiap 2 detik di 100.000 koneksi itu 50.000 paket per detik yang tidak membawa data.
Contoh tandingan: aplikasi internal dengan 80 klien di satu node nggak butuh registri terdistribusi atau backoff canggih. Satu node dan reconnect sederhana sudah cukup. Tambah mekanisme saat jumlah node dan klien menuntutnya.
Latihan
Gateway punya 4 node, masing-masing 50.000 koneksi. Satu node di-restart saat deploy.
- Berapa koneksi yang nyambung ulang, dan berapa rata-rata per detik kalau jitter menyebarkannya merata selama 30 detik?
- Tulis batas buffer dan kebijakan untuk dua jenis pesan: pesan chat dan indikator mengetik.
- Pengguna tampak online padahal ponselnya mati 3 menit lalu. Apa yang kemungkinan salah?
Lihat pembahasan
- 50.000 koneksi. Dengan jitter merata selama 30 detik itu sekitar 1.700 sambungan per detik yang dibagi ke 3 node lain, atau sekitar 560 per node. Tanpa jitter, bisa 50.000 dalam satu detik, puluhan kali lebih berat.
- Chat: batas 1.000 pesan atau 1 MB per koneksi. Kalau terlampaui, putus koneksi dan biarkan klien sinkronisasi dari kursor. Mengetik: simpan hanya status terbaru per percakapan, ganti yang lama, jangan antre. Kehilangan satu indikator tidak berdampak.
- Presence bergantung pada event putus, atau TTL terlalu panjang. Ponsel mati nggak mengirim event, jadi node nggak tahu. Pakai TTL 60 detik yang diperpanjang heartbeat, dan pastikan kunci kedaluwarsa tanpa perlu event.
Terkait
- Sebelumnya: M13.01 Pilih kanal real-time.
- Lanjut ke M13.03 Kirim pesan chat, tempat kursor sinkronisasi dan ack didefinisikan.
- Backoff dan jitter mengulang bahasan retry dari M03. Registri dan perutean memakai ide partisi dari M07. Event gagal kirim biasanya masuk antrean dari M10.
Catatan
- Asumsi: WebSocket di belakang load balancer dengan timeout idle sekitar 60 detik.
- Angka interval, TTL, dan batas buffer adalah titik awal. Ukur ulang sesuai jaringan dan klien kamu.
- Yang nggak dibahas: autentikasi token yang kedaluwarsa di tengah koneksi, dan multi-region.
- Terakhir ditinjau: 26 Oktober 2026.