Служба стартует раньше своего сокета
При сокет-активации сокет обязан открыться раньше службы: именно он держит адрес и передаёт дескриптор. Если порядок обратный, служба пытается занять порт сама и получает отказ.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Служба включена в автозапуск вместо сокета
Тогда при загрузке она стартует сама, занимает порт, и сокет уже не может открыться.
-
Служба требуется другим unit напрямую
Если кто-то объявил
Requires=myapp.service, служба поднимется в обход сокета. -
Служба не связана с сокетом
При несовпадении имён связь не устанавливается, и systemd не считает сокет источником активации.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Адреса, сокеты и активируемые ими службы.
systemctl list-sockets --no-pagerСвязь между сокетом и службой с обеих сторон.
systemctl show myapp.socket -p Service && systemctl show myapp.service -p SocketsПорядок событий при загрузке.
journalctl -b -u myapp.socket -u myapp.service --no-pager | head -20Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Тогда при загрузке она стартует сама, занимает порт, и сокет уже не может открыться.
- Как проверить
-
Посмотрите состояния включения обоих unit.
systemctl is-enabled myapp.service myapp.socket
- Как исправить
-
В автозапуске должен быть только сокет.
sudo systemctl disable myapp.service && sudo systemctl enable --now myapp.socket
- Почему происходит
- Если кто-то объявил
Requires=myapp.service, служба поднимется в обход сокета.
- Как проверить
-
Посмотрите, кто зависит от службы.
systemctl list-dependencies --reverse myapp.service --no-pager | head
- Как исправить
-
Замените зависимость на сокет: другие unit должны требовать
myapp.socket.
- Почему происходит
- При несовпадении имён связь не устанавливается, и systemd не считает сокет источником активации.
- Как проверить
-
Посмотрите связь в обе стороны.
systemctl show myapp.socket -p Service systemctl show myapp.service -p Sockets
- Как исправить
-
Укажите связь явно:
Service=в сокете илиSockets=в службе.
Пример вывода
Служба заняла порт раньше сокета. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
systemd[1]: Started myapp.service - My application.
systemd[1]: myapp.socket: Failed to listen on sockets: Address already in use
systemd[1]: Failed to listen on myapp.socket - Socket for myapp.
Связанные ошибки
- Сокет и служба включены одновременно: конфликт при загрузке При сокет-активации в автозапуск включена и служба, и сокет. Порт занимает то, что стартовало первым.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Служба не получает сокет при сокет-активации Сокет активен, служба запускается, но не находит переданный дескриптор. Разбор: Accept, FileDescriptorName, соответствие имён.
- Dependency failed for … и результат 'dependency' Сообщение Dependency failed for: служба не запускалась, потому что упала её зависимость. Как найти настоящего виновника.
- Found ordering cycle: циклическая зависимость при загрузке systemd нашёл цикл в порядке запуска и разорвал его, отбросив одну зависимость. Как найти цикл и правильно расставить After и Requires.
- Замаскированная зависимость мешает загрузке Служба не запускается, потому что замаскирован unit, который она требует. Как найти все замаскированные unit.
- Контейнеры не поднимаются при загрузке сервера Контейнеры с политикой перезапуска не стартуют после перезагрузки: docker не включён, тома на неподмонтированном разделе, своя служба без зависимостей.
- Цель не достигнута: служба ждёт target, который не наступает Служба не запускается, потому что не достигнута цель из After= или Requires=. Разбор целей multi-user, network-online, graphical.
Источники
-
systemd.socket(5)
Порядок активации сокета и службы. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено включением службы в автозапуск при сокет-активации.