У нас сайт с высокой посещаемостью. За последние несколько дней у нас было несколько клиентов, которые жаловались на спорадические простои, которые мы не можем воспроизвести. У нас есть несколько веб-серверов, выбранных для приема трафика от нашего балансировщика нагрузки, и во время исследования я понял, что все серверы сбрасывают более 20 подключений в секунду. Пример подключения с одного сервера выглядел так:
38452 TIME_WAIT
7815 ESTABLISHED
570 FIN_WAIT2
105 FIN_WAIT1
101 LAST_ACK
36 SYN_RECV
25 CLOSING
4 SYN_SENT
2 CLOSE_WAIT
1 Foreign
Наш настроенный диапазон портов в настоящее время установлен на 15000 61000
на всех серверах. Таким образом, может показаться, что все возможные порты должны быть исчерпаны, поскольку количество соединений, установленных или ожидающих закрытия, равно 46267.
Что нам делать с разорванными соединениями, пока мы исследуем трафик? Может быть, стоит увеличить диапазон портов? Уменьшить время ожидания закрытия соединений? Обе? Будет ли это иметь потенциально негативные последствия?
Есть несколько способов решить эту проблему.
Самый простой способ - увеличить эфемерный диапазон, но вы уже сделали это, и, очевидно, есть пределы того, как далеко вы можете зайти с этим решением.
Другое решение - это циклический DNS и добавление нескольких IP-адресов к вашим узлам балансировки нагрузки. Иногда это нелегко применить (вам нужно подождать, чтобы получить дополнительные IP-адреса, дождитесь периода распространения DNS и т. Д.).
Две вещи, которые вы можете безопасно сделать немедленно, пока вы рассматриваете другие долгосрочные решения, - это снизить таймеры TCP и включить tcp_reuse.
tcp_reuse довольно безопасно использовать в балансировщике нагрузки, и он позволяет ядру повторно использовать сокеты в состоянии TIME_WAIT для новых подключений. Чтобы включить его, запустите в Linux:
# sysctl -w net.ipv4.tcp_tw_reuse=1
Чтобы сделать загрузку постоянной:
# echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.d/net.ipv4.tcp_tw_reuse.conf
Другие параметры настройки ядра, которые могут помочь:
Кроме того, вы можете уменьшить net.ipv4.tcp_fin_timeout до 1 или 2 (как долго сохранять сокеты в состоянии FIN-WAIT-2, если ваш хост является единственным закрывающим соединением).
Надеюсь, поможет.