Все об Arch Linux

Arch Linux будет тем, что вы из него сделаете!

Свободный порт уже занят: как найти и убить процесс

Запустил сервер, а он падает с «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.

Полезные ресурсы



Не получилось? Поможем настроить

Задай вопрос в чате — отвечаем быстро, по делу и без воды.

Читайте также

Комментарии

Загрузка…

Откроется GitHub: создайте новый issue с вашим комментарием (кнопка «Submit new issue»). После отправки обновите эту страницу — комментарий появится ниже.

Telegram Max