Убитый процесс блокирует TCP-порты.

Вопрос или проблема

У меня была эта проблема на нескольких машинах. Есть ли какой-то способ освободить этот заблокированный порт? Вот пример:

Позвольте объяснить. Я завершил некоторое JAVA-процесс на SUSE Linux Enterprise Server 11 SP4, который имел открытые порты. Я использовал команду “kill -9” с пользователем root. Теперь невозможно снова запустить процесс, потому что порт всё ещё заблокирован. Приложение умирает, когда порт всё ещё открыт. Но процесс однозначно исчез!

Когда я смотрю с помощью команды
netstat -anop | grep -E "Sta|37941"
(также с пользователем root), я получаю следующие результаты:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    Timer
[...]
tcp        0      0 172.21.63.27:42034      172.21.63.28:37941      ESTABLISHED -                   keepalive (2861.75/0/0)
[...]

Он не показывает PID! До завершения процесса он показывал PID процесса. Есть ли какой-либо способ освободить такой «мертвый» порт? Нам всегда нужно перезагружать операционную систему, чтобы снова запустить приложение. Но это действительно, действительно критически важно для наших систем с высокой доступностью… что делать, если нам нужно будет завершить процесс в будущем? Эта проблема также происходила и на других операционных системах unix в прошлом.

Любая помощь в решении этой проблемы в будущем будет очень оценена. Большое спасибо всем заранее!

Попробуйте, чтобы увидеть, какой процесс (включая PID) использует порт:

netstat -tupln |grep ":<Ваш_Порт_Здесь>"

Затем завершите PID (рядом с названием процесса) обычным образом. Не используйте команду kill с какими-либо параметрами.

kill <pid>

Примечание: Не голосуйте против, если не пробовали!

Ответ или решение

Когда работа с сетевыми портами на сервере сталкивается с проблемой, когда порты остаются заблокированными после завершения процесса, это может представлять серьёзную угрозу для систем с высоким уровнем доступности. Проблема особенно актуальна для серверов, таких как SUSE Linux Enterprise Server 11 SP4, где порты остаются активными даже после насильственного завершения процесса с помощью команды kill -9. В этой ситуации важно глубже понять, почему это происходит и как это можно избежать.

Теория

Когда процесс открывает TCP-соединение на машине, он использует комбинацию локального адреса и номера порта для идентификации каждого соединения. В нормальных условиях, когда процесс завершает работу корректно, операционная система освобождает ассоциированные с ним ресурсы, включая порты. Однако, если процесс завершен принудительно, как это происходит при использовании kill -9, он не получает возможности корректно очистить свое состояние, что может привести к тому, что порт остается заблокированным, даже если сам процесс больше не существует. Порт находится в состоянии ожидания завершения соединения (TIME_WAIT), что мешает другому процессу использовать эти же сетевые параметры.

В данном контексте команда netstat -anop | grep -E "Sta|<номер_порта>", которой вы пользовались, показывает, что TCP-соединение остаётся в состоянии ESTABLISHED даже после завершения процесса. На это может влиять сетевой стек, который всё ещё ожидает завершения текущих операций.

Пример

Вы столкнулись с ситуацией на SUSE Linux Enterprise Server 11 SP4, где после завершения JAVA-процесса порты оставались заблокированными. Остановив процесс с kill -9, вы обнаружили, что номер PID больше не отображается при проверке через netstat, но порт остаётся заблокированным. Это типичный пример, когда использование команды kill -9 может вызвать блокировки из-за неправильного завершения сетевых соединений.

Применение

Для решения этой проблемы в будущем следует придерживаться следующих рекомендаций:

  1. Избегайте использования kill -9, если возможно. Вместо этого, используйте kill без параметра для отправки сигнала TERM, который позволяет процессу корректно завершиться, высвободив все ресурсы. Если процесс не завершается, можно медленно повышать уровень сигнала, начиная с TERM, затем HUP, и лишь в крайнем случае использовать kill -9.

  2. Используйте команду lsof -i:<номер_порта> для точной идентификации, какие процессы используют указанный порт. Это может предоставить дополнительную информацию и контекст, если несколько приложений взаимодействуют с одним и тем же портом.

  3. Изменение времени ожидания TIME_WAIT, если это возможно. В некоторых конфигурациях сетевого стека значение времени ожидания TCP может быть уменьшено для ускоренного освобождения порта. Однако это решение должно использоваться с осторожностью, так как оно может повлиять на надёжность сетевых соединений.

  4. Проверка на открытые файловые дескрипторы. Иногда приложение не завершается из-за неочевидных зависимостей. Используя lsof, можно идентифицировать и закрыть эти дескрипторы.

  5. Отслеживание зависимых сервисов и зависимостей процессов. Не исключено, что проблема вызвана зависимостями, которые не были завершены должным образом из-за использования некорректной последовательности в остановке процессов.

  6. Автоматика и мониторинг систем. Внедрите системы мониторинга и автоматизации, которые будут отслеживать состояния портов и процессов. Это поможет своевременно обнаруживать подобные проблемы и автоматизировать безопасное завершение процессов.

Следуя этим рекомендациям, можно минимизировать влияние заблокированных портов на серверы и повышать стабильность и доступность сервисов. Если проблема всё ещё не решается, рекомендуется обратиться за консультацией к специалистам по операционной системе или сетевой инфраструктуре, чтобы получить более точное и детализированное решение.

Оцените материал
Добавить комментарий

Капча загружается...