Son zamanlarda, bir veritabanı sunucusu kaybolması poll()
bağlı bir istemci için 2 saat ( libpq istemci kitaplığında bir çağrı için uzun süre beklemek) kadar askıya neden üretim, bir sorun izlemek için biraz zaman geçirdim . Sorunu inceleyerek, kopmuş TCP bağlantılarının zamanında fark edilebilmesi için bu çekirdek parametrelerinin aşağı doğru ayarlanması gerektiğini fark ettim:
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries2 = 15
Yukarıdaki dört değer bir Ubuntu 12.04 makinesindendir ve bu varsayılanların geçerli Linux çekirdek varsayılanlarından farklı olduğu görülmektedir .
Bu ayarlar, mevcut bir bağlantıyı açık tutmaya ve tutma probları ile son derece cimri olmaya eğilimli görünüyor. AIUI, varsayılan tcp_keepalive_time
2 saat, uzak bir ana bilgisayar için bir yanıt beklediğimiz anlamına gelir, bağlantımızın hala geçerli olduğunu doğrulamak için bir koruma probu başlatmadan önce 2 saat sabırla bekleyeceğiz. Ve sonra, uzak ana makine bir tutma probuna yanıt vermezse, bu tutma problarını 9 kez ( tcp_keepalive_probes
), 75 saniye arayla ( tcp_keepalive_intvl
) yeniden deneriz , bu yüzden bağlantının gerçekten öldüğüne karar vermeden önce 11 dakika daha fazla olur.
Bu, alanda gördüklerimle eşleşiyor: örneğin, psql
uzak bir PostgreSQL örneğine bağlı bir oturum başlatırsam , bazı sorgularda yanıt beklerken
SELECT pg_sleep(30);
ve sonra uzak sunucunun korkunç bir ölümle ölmesini sağlayın (örneğin, o makineye trafik bırakın), psql oturumumun bağlantısının öldüğünü anlamadan önce 2 saat 11 dakika kadar beklediğini görüyorum. Tahmin edebileceğiniz gibi, bu varsayılan ayarlar, bir veritabanı yerine çalışma olayı sırasında bir veritabanıyla konuştuğumuz kod için ciddi sorunlara neden olur. Bu düğmeleri kapatmak çok yardımcı oldu! Ve bu varsayılanların düzeltilmesini tavsiye etmede yalnız olmadığımı görüyorum .
Yani sorularım:
- Varsayılanlar ne kadar zamandır böyle?
- Bu TCP ayarlarını varsayılan yapmak için orijinal gerekçe neydi?
- Herhangi bir Linux dağıtımı bu varsayılan değerleri değiştirir mi?
Ve bu ortamların gerekçesi ile ilgili diğer herhangi bir tarih veya perspektif takdir edilecektir.
TCP_KEEPIDLE
, TCP_KEEPCNT
ve TCP_KEEPINTVL
.
TCP_USER_TIMEOUT
ayar yapmak yerine soket seçeneğini de belirtmek mümkün olmalıdır net.ipv4.tcp_retries2
. Tabii ki birçok uygulama (buradaki örneğimdeki PostgreSQL gibi) TCP_USER_TIMEOUT
henüz desteklemiyor .