Вопрос или проблема
У меня была эта проблема на нескольких машинах. Есть ли какой-то способ освободить этот заблокированный порт? Вот пример:
Позвольте объяснить. Я завершил некоторое 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
может вызвать блокировки из-за неправильного завершения сетевых соединений.
Применение
Для решения этой проблемы в будущем следует придерживаться следующих рекомендаций:
-
Избегайте использования
kill -9
, если возможно. Вместо этого, используйтеkill
без параметра для отправки сигналаTERM
, который позволяет процессу корректно завершиться, высвободив все ресурсы. Если процесс не завершается, можно медленно повышать уровень сигнала, начиная сTERM
, затемHUP
, и лишь в крайнем случае использоватьkill -9
. -
Используйте команду
lsof -i:<номер_порта>
для точной идентификации, какие процессы используют указанный порт. Это может предоставить дополнительную информацию и контекст, если несколько приложений взаимодействуют с одним и тем же портом. -
Изменение времени ожидания TIME_WAIT, если это возможно. В некоторых конфигурациях сетевого стека значение времени ожидания TCP может быть уменьшено для ускоренного освобождения порта. Однако это решение должно использоваться с осторожностью, так как оно может повлиять на надёжность сетевых соединений.
-
Проверка на открытые файловые дескрипторы. Иногда приложение не завершается из-за неочевидных зависимостей. Используя
lsof
, можно идентифицировать и закрыть эти дескрипторы. -
Отслеживание зависимых сервисов и зависимостей процессов. Не исключено, что проблема вызвана зависимостями, которые не были завершены должным образом из-за использования некорректной последовательности в остановке процессов.
-
Автоматика и мониторинг систем. Внедрите системы мониторинга и автоматизации, которые будут отслеживать состояния портов и процессов. Это поможет своевременно обнаруживать подобные проблемы и автоматизировать безопасное завершение процессов.
Следуя этим рекомендациям, можно минимизировать влияние заблокированных портов на серверы и повышать стабильность и доступность сервисов. Если проблема всё ещё не решается, рекомендуется обратиться за консультацией к специалистам по операционной системе или сетевой инфраструктуре, чтобы получить более точное и детализированное решение.