Свободный порт уже занят: как найти и убить процесс
Запустил сервер, а он падает с «Address already in use»? Порт свободен, но занять его никто не даёт? Скорее всего, на этом порту сидит мёртвый процесс, который не хочет отдавать ресурс. Вот быстрое решение: найди виновника через ss и убери через pkill.
ss -tlnp | grep :8080 # кто занял порт
pkill myserver # убить процесс
Три команды, десять секунд, проблема решена. А дальше разберёмся, почему так происходит и как защититься от повторения.
Почему занятый порт блокирует всё подряд
TCP-порт это ресурс, который ядро отдаёт процессу на время работы. Процесс «слушает» порт, принимает соединения, обрабатывает данные. Когда процесс падает или зависает, ядро не всегда моментально освобождает сокет. Есть состояние TIME_WAIT (обычно до 60 секунд), а бывает и хуже: процесс жив, но уже не работает. Он молча держит порт.
Стандартная ошибка выглядит так:
Error: listen EADDRINUSE: address already in use :::8080
Или на уровне systemd:
Failed to create listen socket: Address already in use
Причём страдает не только тот сервис, который ты запускаешь. Если это системный порт, например 53 (DNS), может не подняться сетевой стек целиком. Wi-Fi вроде подключился, а DNS не резолвится, сайты не открываются. Всё из-за одного зависшего процесса.
Как найти, кто занял порт
Тут помогает утилита ss из пакета iproute2. Он уже есть в любой свежей установке Arch.
Покажи все слушающие TCP-порты и найди нужный:
ss -tlnp | grep :8080
Вывод будет таким:
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("nginx",pid=1423,fd=6))
Обрати внимание на колонку users:. Тут написано имя процесса и его PID. Теперь точно знаешь, кто виноват.
Если порт неизвестен, посмотри все слушающие сокеты сразу:
ss -tlnp
Расшифровка флагов:
-t: только TCP-l: только слушающие (listening)-n: без преобразования имён (показывает числовые порты)-p: показать процесс (нужны права root для чужих процессов)
Без sudo ты увидишь только свои процессы. Если в колонке users стоит * или её нет вовсе, запусти с sudo ss -tlnp.
Как убить зависший процесс
Нашёл PID? Убивай:
kill 1423
Не помогло (процесс упёрся и не закрывается)? Жёстче:
kill -9 1423
А если знаешь только имя процесса, воспользуйся pgrep для поиска и pkill для убийства:
pgrep -a nginx # покажет PID и команду запуска
pkill nginx # убьёт все процессы с таким именем
pgrep -a полезен: показывает полную команду, по которой легко понять, какой именно экземпляр запущен. Вдруг два nginx с разными конфигами?
Если один процесс не закрывается, pkill тоже можно направить через kill -9:
pkill -9 nginx
После убийства подожди секунду и запускай сервис заново:
sleep 1 && systemctl start myserver
Как защититься от проблемы на будущее
Авто-перезапуск через systemd
Если сервис падает и порт зависает, настрой Restart=always в юните:
[Service]
Restart=always
RestartSec=3
При нештатном завершении systemd сам перезапустит сервис через три секунды. Но если процесс не падает, а просто зависает, это не поможет.
Периодическая проверка скриптом
Для критичных портов можно добавить cron-задачу:
#!/bin/bash
if ! ss -tlnp | grep -q ':8080'; then
systemctl start myserver
fi
Элементарно, но работает: если порт мёртв, сервис поднимется сам.
Добавление в TROUBLESHOOTER
Как показывает практика, заведи файл-журнал проблем. Фиксируй: дата, симптом, корневая причина, решение. Со временем получится персональная база знаний. Подробнее про настройку Wi-Fi через wpa_supplicant и другие сетевые тонкости читай в соответствующих статьях блога.
Типичные ситуации и решения
Сервер не стартует, ошибка «Address already in use»
ss -tlnp | grep :<порт>
pkill <имя_процесса>
systemctl start <имя_сервиса>
Сеть не поднимается после аварийного завершения
Случай из практики: висит процесс, держит порт DNS, весь сетевой стек встаёт. Проверь порты 53 и 80:
ss -tlnp | grep -E ':53|:80'
Нашёл мёртвый процесс? Убей и перезапусти systemd-resolved или NetworkManager.
Несколько экземпляров одного процесса
pgrep -a python3
Если видишь два или более PID, а нужен только один, убей лишние:
pkill -f "python3 myserver.py"
Флаг -f совпадает по полной команде, а не только по имени бинарника. Это безопаснее: не зацепит похожие скрипты.
Частые вопросы
Что такое TIME_WAIT и нужно ли с ним бороться?
TIME_WAIT: состояние сокета после закрытия соединения. Ядро ждёт около 60 секунд, пока придут запоздалые пакеты, и не даёт переназначить порт. В большинстве случаев достаточно подождать. Настройка net.ipv4.tcp_tw_reuse разрешает повторное использование, но лезть в эту настройку стоит только при реальной проблеме.
Почему ss не показывает PID?
Ты запустил команду без root-привилегий. Добавь sudo:
sudo ss -tlnp
Как убить процесс, если я не знаю его имя?
Посмотри полный список слушающих портов, найди порт в выводе, прочитай имя в колонке users:
ss -tlnp
Чем ss лучше netstat?
netstat из пакета net-tools давно не обновляется и медленнее ss. Arch Linux поставляет iproute2 (содержащий ss) по умолчанию. Подробнее на странице ArchWiki про ss.
Могу ли я использовать lsof вместо ss?
Да, lsof -i :8080 покажет то же самое. Но ss быстрее и не требует дополнительной установки. Кому что ближе, тот тем и пользуйся.
Заключение
Проблема «свободный порт занят» решается за минуту. Нашёл виновника через ss -tlnp, убил через pkill, перезапустил сервис. Если поломка повторяется, настрой авто-перезапуск в systemd и заведи журнал проблем. Ключевые инструменты: ss -tlnp для поиска, pgrep -a для проверки, pkill для убийства. Лови момент и действуй.
Если зависания сопровождаются ростом нагрузки на CPU, глянь фикс зависаний при высокой нагрузке CPU: там разобраны причины и решения для другого типа проблем. А если ставишь новый пакет из AUR и ловишь ошибки, поможет руководство по установке из AUR.
Полезные ресурсы
- ArchWiki: Internet connectivity: диагностика сетевых проблем в Arch
Не получилось? Поможем настроить
Задай вопрос в чате — отвечаем быстро, по делу и без воды.

Комментарии