Как создать составной системный блок

802
Martin Mucha

Там у меня есть определенные услуги, которые я обычно начинаю вместе: скажем, зоокейпер + кафка + элассандра. Есть ли способ, как написать составной блок: все начинается вместе, все умирает вместе? Это означает, что если я начну это, то ему будет поручено все это начать, и наоборот. Что было бы правильным способом сделать это?

6

2 ответа на вопрос

10
grawity

Один из способов состоит в том, чтобы все три службы зависели от оставшихся двух Requires=.

  • one.service: Requires=two.service three.service
  • two.service: Requires=one.service three.service
  • три.сервис: и т. д.

Это не создаст цикл - зависимости не зависят от порядка запуска.

(Тем не менее, вы должны объявить некоторые До = или После =, например, если kafka нужно запустить после zookeeper.)


Другой метод заключается в создании целевого подразделения, которое зависит от ваших трех служб, а службы должны быть единым PartOf=целым. (К сожалению, пока еще невозможно иметь ConsistsOf = в самой .target.)

  • all.target: Requires=one.service two.service three.service
  • one.service: PartOf=all.target
  • и т.п.

(Опять же, вы должны дополнительно объявить зависимости и порядок между сервисами; не полагайтесь только на .target, запускающий все.)

Большое спасибо, мне нравится в первом подходе, что я могу запустить любую из этих служб, и все будут работать в правильном порядке. И второе пригодится для многозапусковых сервисов, которые не нужно запускать всегда вместе. Спасибо за оба, я буду использовать их - оба. Martin Mucha 6 лет назад 1
4
Filipe Brandenburger

Да, есть несколько способов сделать это.

Самый простой (который выполняет некоторые из описанных вами действий, но не все) - создать целевой модуль и добавить зависимости от ваших сервисных модулей (например, Requires=zookeeper.service kafka.service elassandra.serviceа также установить After=те же модули). Целевой модуль полезен при запуске всех эти юниты вместе, но на самом деле это не поможет вам остановить их все вместе (использование systemctl stopна целевом юните не остановит его зависимости.) Есть способы, которыми вы можете остановить юниты, например systemctl isolate multi-user.target, остановите все юниты, которые не являются зависимостями этого цель, что означает, что юниты, запущенные вручную, будут остановлены, но это намного сильнее, чем остановка небольшого набора юнитов, так что, вероятно, не очень подходит ...

Возможно, лучшим подходом является использование PartOf=директивы, которая в точности соответствует описанию. Вы можете либо создать «фиктивный» сервисный блок для совместного управления всеми сервисами, либо выбрать один из ваших сервисов, а другие сделать PartOfэтот сервис одним.

Вам необходимо настроить PartOf=все модули, которые вы хотите запускать и останавливать вместе, в вашем случае zookeeper.service, kafka.service и elassandra.service. Но учтите, что вам не обязательно изменять сами файлы сервисного модуля (например, если они поставляются с самим программным обеспечением в пакетах deb или rpm.) Вы можете использовать файлы переопределения (которые вы можете создать с помощью systemctl edit), чтобы добавить небольшой фрагмент конфигурации для существующего модуля, который позволит вам легко определить PartOf=отношения между модулями, даже если они определены в файлах, которые вы предпочитаете не изменять.

Нет необходимости в `After` в цели. Архитектура здесь нерегулярная. JdeBP 6 лет назад 1
спасибо за ваш ответ, а именно за переопределения единиц, я не знал об этом. Спасибо! Обидно, я могу отметить только один действительный ответ. Еще раз спасибо! Martin Mucha 6 лет назад 1