Linux: как убить программы, использующие порт 1935?
У меня есть red5 server (JAVA), работающий на моем сервере Linux.
Иногда сервер выключается. При попытке перезапустить его я получил ошибку:
"Ошибка привязки, этот порт alerady в использовании".
Поэтому я пытаюсь убить сервер с помощью killall -9 java и попробуйте перезагрузить сервер: та же ошибка.
Я должен подождать некоторое время (около 2-3 минут) и перезапустить его снова: это работает.
Мне просто нужно знать, почему, когда я убиваю процесс, я все равно придется подождать 2-3 минуты, прежде чем порт 1935 освободится, и я снова смогу запустить сервер.
Есть ли способ немедленно остановить этот процесс и освободить порт ?
6 ответов:
Если вы уверены, что старый экземпляр вашего сервера содержит порт, просто запустите
jps
, найдите pid вашего сервера в списке и запуститеkill -9 my_pid
Для общего процесса, не связанного с java,
lsof -i :1935
обычно работает для меня. Опять же, возьмите pid и убейте этот процесс.
Проблема заключается в
-9
в убийстве.Если вы убиваете процесс с помощью SIGKILL (-9), процесс немедленно завершается. Таким образом, порт остается выделенным до тех пор, пока (несколько минут спустя) операционная система не заметит проблему. Попробуйте запустить его и радиоразведки (в порядке) прежде чем сигнал SIGKILL.
В любом случае используйте
netstat -a -t -p
, чтобы проверить, какой процесс получил порт.
Если это возможно, вы должны использовать опцию socket
SO_REUSEADDR
, когда ваша программа устанавливает свой сокет. Таким образом, вы можете сразу же повторно использовать сокет при перезапуске программы, вместо того, чтобы ждать 2-3 минуты.Смотрите javadoc setReuseAddress для получения дополнительной информации. В частности:
При закрытии TCP-соединения соединение может оставаться в состоянии ожидания в течение некоторого периода времени после закрытия соединения (обычно называемого состоянием TIME_WAIT или 2MSL состояние ожидания). Для приложений, использующих хорошо известный адрес сокета или порт, может оказаться невозможным привязать сокет к требуемому SocketAddress, если есть соединение в состоянии таймаута, включающее адрес сокета или порт.
Включение SO_REUSEADDR перед привязкой сокета с помощью bind (SocketAddress) позволяет привязать сокет, даже если предыдущее соединение находится в состоянии таймаута.