У нас есть пара производственных систем, которые недавно были преобразованы в виртуальные машины. Есть наше приложение, которое часто обращается к базе данных MySQL, и для каждого запроса оно создает соединение, запросы и разрывает это соединение.
Это неподходящий способ запроса (я знаю), но у нас есть ограничения, которые мы не можем обойти. В любом случае проблема в следующем: пока машина была физическим хостом, программа работала нормально. После преобразования в виртуальную машину мы заметили периодические проблемы с подключением к базе данных. В какой-то момент было более 24000 соединений сокетов в TIME_WAIT (на физическом хосте максимальное количество, которое я видел, было 17000 - не очень хорошо, но не вызывает проблем).
Я бы хотел, чтобы эти подключения использовались повторно, чтобы мы не видели проблемы с подключением, и поэтому:
Вопросы:
Можно ли установить значение tcp_tw_reuse равным 1? Какие очевидные опасности? Есть ли причина, по которой я должен никогда сделай это?
Кроме того, есть ли другой способ получить систему (RHEL / CentOS), чтобы предотвратить переход такого количества соединений в TIME_WAIT или их повторное использование?
И наконец, что изменит tcp_tw_recycle и поможет ли это мне?
Заранее спасибо!
Вы можете безопасно сократить время простоя, но вы можете столкнуться с проблемами из-за неправильно закрытых соединений в сетях с потерей пакетов или джиттером. Я бы не стал начинать настройку с 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, знает, какая степень надежности ей нужна, и поэтому она должна иметь возможность определять продолжительность задержки TIME-WAIT для получателя 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.
Я думаю, что можно изменить это значение на 1. Более подходящим способом может быть использование команды:
[root@server]# sysctl -w net.ipv4.tcp_tw_reuse=1
Я не знаю очевидных опасностей, но быстрый поиск в Google дает следующее ссылка на сайт который утверждает, что tcp_tw_reuse
это лучшая альтернатива, чем tcp_tw_recycle
, но в любом случае его следует использовать с осторожностью.
Это не отвечает на ваш вопрос (и это с опозданием на 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 в качестве примера того, как это сделать (это включает сообщения поддержки активности, но включение SO_REUSEPORT очень похоже). Если ваше устаревшее приложение с плохим поведением использует IPv6, не забудьте изменить строку 55 libkeepalive.c
из
if((domain == PF_INET) && (type == SOCK_STREAM)) {
к
if(((domain == PF_INET) || (domain == PF_INET6)) && (type == SOCK_STREAM)) {
Если вы застряли, пришлите мне электронное письмо, я напишу код и отправлю его вам.
Соединение не может быть повторно использовано, если они находятся в режиме TIME WAIT. Если у вас нет потери пакетов в сети между приложением и MySQL, вы можете уменьшить время ожидания.
Однако лучшим решением является использование постоянных подключений к базе данных и пулу подключений.