Saya menghabiskan beberapa waktu untuk melacak masalah dalam produksi baru-baru ini, di mana server database menghilang akan menyebabkan hang hingga 2 jam (lama menunggu poll()
panggilan di perpustakaan klien libpq) untuk klien yang terhubung. Menggali masalah, saya menyadari bahwa parameter kernel ini harus disesuaikan agar koneksi TCP terputus agar diperhatikan secara tepat waktu:
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries2 = 15
Keempat nilai di atas berasal dari mesin Ubuntu 12.04, dan sepertinya default ini tidak berubah dari default kernel Linux saat ini .
Pengaturan ini tampaknya sangat bias menjaga koneksi yang ada terbuka, dan menjadi sangat pelit dengan probe keepalive. AIUI, standarnyatcp_keepalive_time
2 jam berarti ketika kami menunggu respons untuk host jarak jauh, kami akan menunggu dengan sabar selama 2 jam sebelum memulai penyelidikan keepalive untuk memverifikasi koneksi kami masih valid. Dan kemudian, jika host jarak jauh tidak menanggapi probe keepalive, kami coba lagi probe keepalive tersebut 9 kali ( tcp_keepalive_probes
), berjarak 75 detik terpisah ( tcp_keepalive_intvl
), jadi itu tambahan 11 menit sebelum kami memutuskan koneksi benar-benar mati.
Ini cocok dengan apa yang saya lihat di lapangan: misalnya, jika saya memulai psql
sesi yang terhubung dengan instance PostgreSQL jarak jauh, dengan beberapa permintaan menunggu jawaban, misalnya
SELECT pg_sleep(30);
dan kemudian memiliki server jauh mati dengan kematian yang mengerikan (misalnya, drop traffic ke mesin itu), saya melihat sesi psql saya menunggu hingga 2 jam dan 11 menit sebelum menemukan koneksi yang mati. Seperti yang Anda bayangkan, pengaturan default ini menyebabkan masalah serius untuk kode yang kita bicarakan dengan basis data selama, katakanlah, peristiwa kegagalan basis data. Mengecilkan tombol-tombol ini sangat membantu! Dan saya melihat bahwa saya tidak sendirian dalam merekomendasikan default ini disesuaikan.
Jadi pertanyaan saya adalah:
- Berapa lama standarnya seperti ini?
- Apa dasar pemikiran asli untuk menjadikan pengaturan TCP ini sebagai default?
- Apakah ada distro Linux yang mengubah nilai default ini?
Dan setiap sejarah atau perspektif lain tentang alasan pengaturan ini akan dihargai.
TCP_KEEPIDLE
, TCP_KEEPCNT
dan TCP_KEEPINTVL
.
TCP_USER_TIMEOUT
, alih-alih mengatur seluruh net.ipv4.tcp_retries2
sistem. Tentu saja banyak aplikasi (seperti PostgreSQL dalam contoh saya di sini) belum mendukung TCP_USER_TIMEOUT
.