Linux: как убить программы, использующие порт 1935?


У меня есть red5 server (JAVA), работающий на моем сервере Linux.

Иногда сервер выключается. При попытке перезапустить его я получил ошибку:

"Ошибка привязки, этот порт alerady в использовании".

Поэтому я пытаюсь убить сервер с помощью killall -9 java и попробуйте перезагрузить сервер: та же ошибка.

Я должен подождать некоторое время (около 2-3 минут) и перезапустить его снова: это работает.

Мне просто нужно знать, почему, когда я убиваю процесс, я все равно придется подождать 2-3 минуты, прежде чем порт 1935 освободится, и я снова смогу запустить сервер.

Есть ли способ немедленно остановить этот процесс и освободить порт ?

6 8

6 ответов:

Если вы уверены, что старый экземпляр вашего сервера содержит порт, просто запустите jps, найдите pid вашего сервера в списке и запустите kill -9 my_pid

Для общего процесса, не связанного с java, lsof -i :1935 обычно работает для меня. Опять же, возьмите pid и убейте этот процесс.

Проблема заключается в -9 в убийстве.

Если вы убиваете процесс с помощью SIGKILL (-9), процесс немедленно завершается. Таким образом, порт остается выделенным до тех пор, пока (несколько минут спустя) операционная система не заметит проблему. Попробуйте запустить его и радиоразведки (в порядке) прежде чем сигнал SIGKILL.

В любом случае используйте netstat -a -t -p, чтобы проверить, какой процесс получил порт.

Немедленное завершение процесса и освобождение порта:

 fuser -k 1935/tcp

Если это возможно, вы должны использовать опцию socket SO_REUSEADDR, когда ваша программа устанавливает свой сокет. Таким образом, вы можете сразу же повторно использовать сокет при перезапуске программы, вместо того, чтобы ждать 2-3 минуты.

Смотрите javadoc setReuseAddress для получения дополнительной информации. В частности:

При закрытии TCP-соединения соединение может оставаться в состоянии ожидания в течение некоторого периода времени после закрытия соединения (обычно называемого состоянием TIME_WAIT или 2MSL состояние ожидания). Для приложений, использующих хорошо известный адрес сокета или порт, может оказаться невозможным привязать сокет к требуемому SocketAddress, если есть соединение в состоянии таймаута, включающее адрес сокета или порт.

Включение SO_REUSEADDR перед привязкой сокета с помощью bind (SocketAddress) позволяет привязать сокет, даже если предыдущее соединение находится в состоянии таймаута.

Kill -9 не должен использоваться по умолчанию. Процесс не может очистить внутренние вещи. Чтобы убить pid приложения, использующего exemple port 8000:

kill $(netstat -nptl | awk '/:8000/{gsub("/.*", ""); print $7}')

Это удобный oneliner:

kill $(fuser 1935/tcp)