Я планирую разместить несколько экземпляров одного и того же веб-приложения для клиентов systemd
. Я хотел бы иметь возможность stop
и start
каждый экземпляр клиента с использованием systemd
, а также обрабатывать всю коллекцию экземпляров клиентов в качестве одной службы , которые могут быть остановлены и начали вместе.
systemd
кажется, предоставляет необходимые мне строительные блоки PartOf
и файлы модулей шаблона, но я остановил родительскую службу, дочерняя служба поддержки клиентов не остановилась. Как я могу заставить это работать с systemd? Вот что у меня так далеко.
Файл родительского блока app.service
:
[Unit]
Description=App Web Service
[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal
Файл шаблона модуля с именем app@.service
, используемый для создания экземпляров клиента:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
Мой app-poc.sh
сценарий (подтверждение концепции, которая просто печатает в файл журнала в цикле):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
Для подтверждения концепции у меня есть файлы модулей systemd ~/.config/systemd/user
.
Затем я запускаю родителя и экземпляр на основе шаблона (после systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start app@customer.service
Из использования journalctl -f
я вижу, что оба запустились и что экземпляр клиента продолжает работать. Теперь я ожидаю, что закрытие родителя остановит ребенка (потому что я использовал PartOf
), но это не так. Кроме того, запуск родителя не запускает ребенка, как ожидалось.
systemctl --user stop app
Благодарность!
(Я использую Ubuntu 16.04 с systemd 229).
Requires=
вместо этого?Ответы:
Вам нужно переместить линию
из
[Service]
и в[Unit]
разделе, и добавить к[Unit]
изapp.service
списка клиентов , чтобы начать, например ,или, как сказал источник в комментариях,
Requires=
то же самое. Вы можете оставитьPartOf
службы, которые вы запускаете вручную, которых нет в списке выше, напримерsystemctl --user start app@customer3.service
.источник
PartOf
. Благодарю. Я собираюсь обработать «Wants» через символическую ссылку, которая станет единственным действием, которое мне нужно предпринять, чтобы активировать нового клиента с помощью systemd. Для моего теста: `ln -s /home/mark/.config/systemd/user/app@.service / home / mark / .config / systemd / user / app.service.wants / unity @ foo.service`Я узнал, что для этого предназначены системные целевые единицы. Используя Target Unit, я получаю преимущества, которые мне нужны, без необходимости создавать поддельный
[Service]
раздел, который я имел выше. Рабочий пример файла «Целевая единица» выглядит так:Затем каждый экземпляр клиента должен быть включен
PartOf
в[Unit]
раздел (как указано @meuh), а также должен иметь[Install]
раздел, чтобыenable
иdisable
работал над конкретной службой:Чтобы вызвать экземпляр клиента и запустить его при запуске цели, используется эта одноразовая команда включения:
Теперь в этот момент я могу использовать
stop
иstart
наapp@customer
к для экземпляра конкретного, или я могу использоватьstart app
иstop app
остановить все приложения вместе.источник
systemctl status $(systemctl list-dependencies --plain otp.target)
systemd
может улучшить удобство использования здесь. Я открыл запрос функции, чтобы предложить улучшенный статус для целей.