
У меня есть следующие единицы:
test_socket_activation.socket
[Unit]
Description="************** MY TEST SOCKET ***************"
PartOf=test_socket_activation.service
[Socket]
ListenStream=127.0.0.1:9991
[Install]
WantedBy=sockets.target
test_socket_activation.service
[Unit]
Description="********** MY TEST SERVICE *****************"
[Service]
ExecStart=/home/xxx/sysadmin/systemd_units/socket_based_activation/testservice.sh
[Install]
WantedBy=multi-user.target
testservice.sh
#!/bin/bash
echo "Socket Service Triggered" > output.txt
Теоретически systemd должен прослушивать порт 127.0.0.1 9991 (через test_scocket_activation.socket). При доступе к сокету systemd должен вызвать родительский модуль (test_scocket_activation.service), который, в свою очередь, должен выполнить скрипт, указанный в директиве ExecStart (testservice.sh), который затем создаст текстовый файл с именем output.txt, чтобы уведомить о доступе к сокету.
Это работает так, как и ожидалось (т. е. output.txt создается при доступе к сокету), за исключением того, что сервисный модуль (test_scocket_activation.service) впоследствии дает сбой из-за "запроса на запуск, повторяющегося слишком быстро, отказываясь запускаться", даже если к сокету обращаются только один раз. Сбой сервиса затем вызывает сбой связанного сокета, который прекращает прослушивание.
Я провел некоторое тестирование, вот мои шаги и результаты журнала:
❯ sudo systemctl start test_socket_activation.socket
❯ sudo systemctl status test_socket_activation.socket
● test_socket_activation.socket - "************** MY TEST SOCKET ***************"
Loaded: loaded (/etc/systemd/system/test_socket_activation.socket; disabled)
Active: active (listening) since Thu 2020-03-19 14:08:40 +01; 17s ago
Listen: 127.0.0.1:9991 (Stream)
Mar 19 14:08:40 toshi systemd[1]: Starting "************** MY TEST SOCKET ***************".
Mar 19 14:08:40 toshi systemd[1]: Listening on "************** MY TEST SOCKET ***************".
❯ эхо "привет" | netcat 127.0.0.1 9991
❯ лс
output.txt testservice.sh
❯ sudo systemctl status test_socket_activation.service
● test_socket_activation.service - "********** MY TEST SERVICE *****************"
Loaded: loaded (/etc/systemd/system/test_socket_activation.service; disabled)
Active: failed (Result: start-limit) since Thu 2020-03-19 14:10:42 +01; 9min ago
Process: 2842 ExecStart=/home/mkr/sysadmin/systemd_units/socket_based_activation/testservice.sh (code=exited, status=0/SUCCESS)
Main PID: 2842 (code=exited, status=0/SUCCESS)
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: test_socket_activation.service start request repeated too quickly, refusing to start.
Mar 19 14:10:42 toshi systemd[1]: Failed to start "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Unit test_socket_activation.service entered failed state.
❯ sudo systemctl status test_socket_activation.socket
● test_socket_activation.socket - "************** MY TEST SOCKET ***************"
Loaded: loaded (/etc/systemd/system/test_socket_activation.socket; disabled)
Active: failed (Result: service-failed-permanent) since Thu 2020-03-19 14:10:42 +01; 41s ago
Listen: 127.0.0.1:9991 (Stream)
Mar 19 14:08:40 toshi systemd[1]: Starting "************** MY TEST SOCKET ***************".
Mar 19 14:08:40 toshi systemd[1]: Listening on "************** MY TEST SOCKET ***************".
Mar 19 14:10:42 toshi systemd[1]: Unit test_socket_activation.socket entered failed state.
❯ sudo journalctl -u test_socket_activation.service
-- Logs begin at Thu 2020-03-19 14:05:23 +01, end at Thu 2020-03-19 14:17:29 +01. --
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: Started "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Starting "********** MY TEST SERVICE *****************"...
Mar 19 14:10:42 toshi systemd[1]: test_socket_activation.service start request repeated too quickly, refusing to start.
Mar 19 14:10:42 toshi systemd[1]: Failed to start "********** MY TEST SERVICE *****************".
Mar 19 14:10:42 toshi systemd[1]: Unit test_socket_activation.service entered failed state.
Как вы можете видеть выше, сокет доступен только ОДИН РАЗ, служба запускается и вызывает скрипт для создания файла output.txt. Но вскоре после этого служба терпит неудачу, поскольку пытается запуститься несколько раз.
У меня следующие вопросы:
Почему служба запускается более одного раза, хотя доступ к сокету осуществляется только один раз (через echo "hello" | netcat 127.0.0.1 9991)?
Как избежать многократного запуска службы, если доступ к сокету осуществляется только один раз?
Все ответы/вклады/идеи будут высоко оценены, спасибо.
решение1
Вы создали Accept=No
сокет, в котором службе передается дескриптор файла прослушиваемого сокета, и ожидается, что она будет принимать соединения, ипродолжай бежать. Выдачей должно быть то, что вы не создали шаблонный блок службы, как это было бы необходимо для Accept=Yes
сокета, где службе передается дескриптор файла подключенного сокета.
дальнейшее чтение
- Джонатан де Бойн Поллард (2019).
tcp-socket-accept
. Руководство по еде. Программное обеспечение. - https://unix.stackexchange.com/a/513663/5132
s6-tcpserver4d
. Лоран Берко. s6-сетевой. skarnet.org.