Опасно ли изменять значение / proc / sys / net / ipv4 / tcp_tw_reuse?

10

У нас есть несколько производственных систем, которые недавно были преобразованы в виртуальные машины. Существует наше приложение, которое часто обращается к базе данных MySQL, и для каждого запроса оно создает соединение, запрашивает и отключает это соединение.

Это не подходящий способ запроса (я знаю), но у нас есть ограничения, которые мы не можем обойти. В любом случае, проблема заключается в следующем: хотя машина была физическим хостом, программа работала нормально. После преобразования в виртуальную машину мы заметили периодические проблемы с подключением к базе данных. В какой-то момент было 24000+ сокетных подключений в TIME_WAIT (на физическом хосте максимум, что я видел, было 17000 - не хорошо, но не вызывало проблем).

Я хотел бы, чтобы эти соединения использовались повторно, чтобы мы не увидели проблему с подключением, и так:

Вопросов:

Можно ли установить значение tcp_tw_reuse равным 1? Каковы очевидные опасности? Есть ли причина, по которой я никогда не должен это делать?

Кроме того, есть ли другой способ заставить систему (RHEL / CentOS) предотвратить попадание такого количества соединений в TIME_WAIT или получить их для повторного использования?

Наконец, что будет делать изменение tcp_tw_recycle, и поможет ли это мне?

Заранее спасибо!

Сагар
источник
1
Эта ссылка хорошо объясняет опасность tcp_tw_recycle и tcp_tw_reuse. Не используйте это.

Ответы:

8

Вы можете безопасно сократить время простоя, но у вас могут возникнуть проблемы с неправильно закрытыми соединениями в сетях с потерей пакетов или дрожанием. Я не стал бы настраивать с 1 секунды, начинал с 15-30 и продолжал свой путь вниз.

Кроме того, вам действительно нужно исправить ваше приложение.

RFC 1185 имеет хорошее объяснение в разделе 3.2:

Когда соединение TCP закрыто, задержка 2 * MSL в состоянии TIME-WAIT связывает пару сокетов на 4 минуты (см. Раздел 3.5 [Postel81]. Приложения, построенные на TCP, закрывают одно соединение и открывают новое (например, соединение передачи данных FTP, использующее режим потока) должно каждый раз выбирать новую пару сокетов. Эта задержка служит двум различным целям:

 (a)  Implement the full-duplex reliable close handshake of TCP. 

      The proper time to delay the final close step is not really 
      related to the MSL; it depends instead upon the RTO for the 
      FIN segments and therefore upon the RTT of the path.* 
      Although there is no formal upper-bound on RTT, common 
      network engineering practice makes an RTT greater than 1 
      minute very unlikely.  Thus, the 4 minute delay in TIME-WAIT 
      state works satisfactorily to provide a reliable full-duplex 
      TCP close.  Note again that this is independent of MSL 
      enforcement and network speed. 

      The TIME-WAIT state could cause an indirect performance 
      problem if an application needed to repeatedly close one 
      connection and open another at a very high frequency, since 
      the number of available TCP ports on a host is less than 
      2**16.  However, high network speeds are not the major 
      contributor to this problem; the RTT is the limiting factor 
      in how quickly connections can be opened and closed. 
      Therefore, this problem will no worse at high transfer 
      speeds. 

 (b)  Allow old duplicate segements to expire. 

      Suppose that a host keeps a cache of the last timestamp 
      received from each remote host.  This can be used to reject 
      old duplicate segments from earlier incarnations of the 

* Примечание: можно утверждать, что сторона, отправляющая FIN, знает, какая степень надежности ему нужна, и поэтому она должна быть в состоянии определить продолжительность задержки ВРЕМЕНИ-ВРЕМЕНИ для получателя FIN. Этого можно достичь с помощью соответствующей опции TCP в сегментах FIN.

      connection, if the timestamp clock can be guaranteed to have 
      ticked at least once since the old conennection was open. 
      This requires that the TIME-WAIT delay plus the RTT together 
      must be at least one tick of the sender's timestamp clock. 

      Note that this is a variant on the mechanism proposed by 
      Garlick, Rom, and Postel (see the appendix), which required 
      each host to maintain connection records containing the 
      highest sequence numbers on every connection.  Using 
      timestamps instead, it is only necessary to keep one quantity 
      per remote host, regardless of the number of simultaneous 
      connections to that host.
duffbeer703
источник
Спасибо за объяснение. Проблема в библиотеке, которую я не могу контролировать.
Сагар
6

Это не отвечает на ваш вопрос (и он опаздывает на 18 месяцев), но предлагает другой способ заставить ваши старые приложения повторно использовать порты:

Полезной альтернативой настройке tcp_tw_reuse(или tcp_tw_recycle) в системе является вставка общей библиотеки (использование LD_PRELOAD) в ваше приложение; эта библиотека может затем разрешить повторное использование порта. Это позволяет вашему устаревшему приложению разрешать повторное использование порта, не применяя его ко всем приложениям в вашей системе (никаких изменений в вашем приложении не требуется), тем самым ограничивая влияние вашей настройки. Например,

    LD_PRELOAD=/opt/local/lib/libreuse.so ./legacy_app

Эта общая библиотека должна перехватывать socket()вызов, вызывать реальный socket () и устанавливать SO_REUSEADDR и / или SO_REUSEPORT в возвращаемом сокете. Посмотрите на http://libkeepalive.sourceforge.net пример того, как это сделать (это включает keepalive, но включение SO_REUSEPORT очень похоже). Если ваше устаревшее приложение с плохим поведением использует IPv6, не забудьте изменить строку 55 libkeepalive.cиз

    if((domain == PF_INET) && (type == SOCK_STREAM)) {

в

    if(((domain == PF_INET) || (domain == PF_INET6)) && (type == SOCK_STREAM)) {

Если вы застряли, пришлите мне письмо, и я напишу код и отправлю его вам.

Марк Виттенберг
источник
6

Я думаю, что можно изменить это значение на 1. Более подходящим способом может быть использование команды:

[root@server]# sysctl -w net.ipv4.tcp_tw_reuse=1

Я не знаю очевидных опасностей, но быстрый поиск в Google выдает эту ссылку, которая подтверждает, что tcp_tw_reuseэто лучшая альтернатива tcp_tw_recycle, но ее следует использовать с осторожностью.

АТХ
источник
2
Нет, это не то, что говорится. Он говорит (говоря о tcp_tw_reuse): «Как правило, это более безопасная альтернатива tcp_tw_recycle».
Фантиус
0

Соединение не может быть повторно использовано, если они находятся в режиме ожидания. Если у вас нет потери пакетов в сети между приложением и MySQL, вы можете уменьшить время ожидания.

Однако лучшее решение - использовать постоянные соединения с базой данных и пул соединений.

Мирча Вуцовичи
источник
1
На самом деле, это не обязательно так. Некоторые системы позволяют использовать сокеты в TIME_WAIT, о чем мой вопрос. Не то, возможно ли это, а каковы очевидные и не столь очевидные опасности. Спасибо!
Сагар