Як вирішили ці настройки за замовчуванням Linux TCP?


13

Нещодавно я витратив досить багато часу на пошук проблеми у виробництві, коли зникнення сервера баз даних призвело б до двох годин (довго чекати poll()виклику в бібліотеці клієнтів libpq) для підключеного клієнта. Розібравшись у проблемі, я зрозумів, що ці параметри ядра повинні бути відрегульовані вниз, щоб своєчасно помітити розірвані TCP-з'єднання:

net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_retries2 = 15

Чотири наведені вище значення - від машини Ubuntu 12.04, і схоже, що ці параметри за замовчуванням не змінюються від поточних стандартних ядер Linux .

Ці налаштування здаються сильно упередженими щодо збереження існуючого з’єднання відкритим і надзвичайно скупими з чутливими зондами. AIUI, за замовчуванням tcp_keepalive_time2 години означає, що коли ми будемо чекати відповіді на віддалений хост, ми будемо терпляче чекати 2 години, перш ніж ініціювати зонд для збереження, щоб переконатися, що наше з'єднання все-таки дійсне. І тоді, якщо віддалений хост не реагує на зонд кепаліву, ми повторюємо ці зонди киепалів 9 разів ( tcp_keepalive_probes), відстань між ними 75 секунд ( tcp_keepalive_intvl), тож це зайві 11 хвилин, перш ніж ми вирішимо, що з'єднання справді мертве.

Це відповідає тому, що я бачив у цьому полі: наприклад, якщо я запускаю psqlсеанс, підключений до віддаленого екземпляра PostgreSQL, із запитом, що чекає відповіді, наприклад

SELECT pg_sleep(30);

а потім віддалений сервер загине жахливою смертю (наприклад, скинути трафік на цю машину), я бачу, як мій сеанс psql чекав до 2 годин і 11 хвилин, перш ніж він з'ясує, що його зв'язок помер. Як ви можете собі уявити, ці налаштування за замовчуванням спричиняють серйозні проблеми для коду, про який ми говоримо з базою даних під час, скажімо, події відмови в базі даних. Відключення цих ручок допомогло дуже багато! І я бачу, що я не один в тому, щоб рекомендувати ці параметри за замовчуванням коригуватися.

Отже, мої запитання:

  • Скільки часу за замовчуванням було таке?
  • Яке оригінальне обґрунтування для встановлення стандартних параметрів TCP?
  • Чи змінюють якісь дистрибутиви Linux ці значення за замовчуванням?

І будь-яка інша історія чи погляд на обґрунтування цих параметрів буде вдячний.


Деякі відповідні відомості тут ... tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
Drav Sloan

Зверніть увагу , що ви можете змінити перші три за з'єднання в коді клієнта з параметрами сокетов TCP_KEEPIDLE, TCP_KEEPCNTі TCP_KEEPINTVL.
wnoise

1
@wnoise насправді з Linux 2.6.37, також слід мати можливість вказати параметр socket TCP_USER_TIMEOUT, а не встановлювати net.ipv4.tcp_retries2загальносистемний. Звичайно, багато програм (наприклад, PostgreSQL в моєму прикладі тут) ще не підтримують TCP_USER_TIMEOUT.
Джош Купершмідт

Відповіді:


6

RFC 1122 в розділі 4.2.3.6 зазначає, що період зберігання не повинен замовчувати менше двох годин.


1
Приємно, дякую, що копали це. Я думаю, що це здебільшого відповідає на питання, чому tcp_keepalive_timeза замовчуванням 7200, хоча мене все ще цікавлять прецедент / пояснення щодо інших трьох відповідних налаштувань.
Джош Купершмідт

Видалення моєї відповіді, як це відповідає на питання (принаймні, на одне із значень)
coteyr

1
@coteyr Все-таки дякую, я ціную зусилля. У вашій відповіді IIRC з'явився інтригуючий коментар, який дозволяє припустити, що в попередніх Linux ядрах за замовчуванням було 15 хвилин. Мене цікавить, як / чому це змінилося на 2 години, або встановити в першу чергу 15 хвилин.
Джош Купершмідт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.