Назад | Перейти на главную страницу

Слишком много установленных подключений осталось открытым

У меня есть (вероятно, довольно старый) сервер CentOS 4.5 с собственным Java-приложением, работающим внутри.

Я обнаружил, что приложение вылетает через некоторое время, и обнаружил, что оно обрабатывает 1024 соединения и пытается открыть еще один сокет, когда оно умирает.

На самом деле, если я проверю ulimit -n Я могу подтвердить, что это 1024, поэтому приложение закрывается, поскольку в нем больше нет свободных файловых дескрипторов.

Что меня беспокоит, так это то, что существуют сотни явно неактивных подключений в состоянии "УСТАНОВЛЕН ВЫКЛЮЧЕНО", все с относительно небольшого количества IP-адресов (около 200), и что они имеют тенденцию складываться с течением времени, и клиенты подключаются, в значительной степени как те, которые я вижу бегущими netstat -nato:

tcp        0      0 ::ffff:10.39.151.20:10000   ::ffff:78.152.97.98:12059   ESTABLISHED off (0.00/0/0)
tcp        0      0 ::ffff:10.39.151.20:10000   ::ffff:78.152.97.98:49179   ESTABLISHED off (0.00/0/0)
tcp        0      0 ::ffff:10.39.151.20:10000   ::ffff:78.152.97.42:45907   ESTABLISHED off (0.00/0/0)

Я знаю, что это не DOS-атака, соединения являются законными, но кажется, что они не закрываются после подключения клиентов и короткого обмена данными с сервером .. кроме того, темп медленный, поскольку они генерируются 200 клиентами (считая другой IP) ..

Следует ли мне исследовать какую-то странную ошибку приложения (возможно, в jre 1.6) или копаться в конфигурации сети CentOS? Я понятия не имею, на что еще смотреть ..

Заранее спасибо, любая подсказка приветствуется!

Гипотеза 1: ваше приложение находится за брандмауэром, который сбрасывает простаивающие tcp-соединения через заданное время.

Когда клиент снова пытается использовать это соединение, он обнаруживает, что оно не отвечает, разрывает его и запускает новое.

Для сервера, поскольку TCP-соединения не имеют таймера проверки активности, невозможно узнать, что соединение недействительно, и оно будет оставаться открытым бесконечно.

Чтобы доказать: сделайте длительный tcpdump одного соединения, чтобы показать, что оно перестает использоваться через заданный промежуток времени.

Решение:

  • Измените код, чтобы использовать поддержку активности на сокетах tcp и (необязательно для лучшей производительности) установите таймер поддержки активности ниже, чем таймер tcp-idle брандмауэра
  • Измените таймер tcp-idle брандмауэра на более высокое значение, превышающее максимальное функциональное время простоя клиента. Скорее всего, это будет глобальная настройка брандмауэра, поэтому ваш администратор безопасности может не захотеть это сделать.