Как перезапустить службу, если ее зависимая служба перезагружена

Служба (скажем, bar.service) зависит от другой службы (скажем, foo.service), например ниже

bar:

[Unit]
After=foo.service
Requires=foo.service
...

Если foo.service перезапущен (вручную или из-за ошибки), как можно также перезапустить bar.service?

Ответ 1

Вы можете использовать PartOf.

[Unit]
After=foo.service
Requires=foo.service
PartOf=foo.service

На странице systemd.unit man:

PartOf =

Настраивает зависимости, аналогичные Requires =, но ограничивается остановкой и перезапуском блоков. Когда systemd останавливает или перезапускает перечисленные здесь единицы, действие распространяется на этот блок. Обратите внимание, что это односторонняя зависимость. Изменения в этом устройстве не влияют на перечисленные единицы.

Ответ 2

Я думаю, что необходимым вариантом является BindsTo, он также обрабатывает неправильные настройки.

[Unit]
Requires=postgresql.service
After=postgresql.service
BindsTo=postgresql.service

BindsTo =

Настраивает зависимости требований, очень похожие по стилю в Requires =. Однако этот тип зависимостей сильнее: в дополнение к эффекту Requires = он объявляет, что если привязанный к нему блок остановлен, это устройство также будет остановлено. Это означает, что устройство, связанное с другим блоком, которое неожиданно переходит в неактивное состояние, также будет остановлено. Единицы могут внезапно неожиданно входить в неактивное состояние по разным причинам: основной процесс сервисного блока может завершиться по собственному выбору, устройство резервного устройства устройства может быть отключено или точка монтирования узла монтирования может быть размонтирована без участия диспетчер системы и службы.

При использовании в сочетании с After = на одном устройстве поведение BindsTo = еще сильнее. В этом случае устройство, строго связанное с ним, должно находиться в активном состоянии, чтобы этот блок также находился в активном состоянии. Это не только означает, что устройство привязано к другому устройству, которое неожиданно переходит в неактивное состояние, но также к тому, которое привязано к другому устройству, которое пропускается из-за неудачной проверки состояния (например, ConditionPathExists =, ConditionPathIsSymbolicLink =,... - см. Ниже) будет остановился, должен ли он работать. Следовательно, во многих случаях лучше всего комбинировать BindsTo = с After =.

Ответ 3

Другим решением может быть использование параметра ExecStartPost для перезапуска bar.service(если он выполняется) при запуске foo.service:

# foo.service
[Service]
ExecStartPost=/bin/systemctl try-restart bar.service
Restart=on-failure
RestartSec=30s

Дополнительные параметры Перезагрузка и RestartSec гарантируют, что foo.service будет автоматически перезагружен при сбое и, следовательно, также bar.service.

Второе расширение my должно быть добавлено к bar.service и гарантировать, что bar.service начнется после foo.service:

# bar.service
[Unit]
After=foo.service

[Service]
Restart=on-failure
RestartSec=30s

Это должно автоматически запускаться обе службы в случае сбоя и бара. Сервис будет перезапущен при перезапуске foo.service(из-за ошибки или ручного запуска).