SystemD порождает N процессов?

13

В моей организации у нас есть ряд рабочих процессов, потребляющих очередь. В настоящее время мы используем SupervisorD для управления ими, но хотели бы использовать SystemD, если это возможно, для достижения определенных преимуществ. У меня достаточно опыта в написании пользовательских модулей, но у меня не сразу есть аналог в SystemD для этого.

В документации SupervisorD параметр называется numprocsподробным, что позволяет установить количество процессов, которые они хотели бы запустить со службой. Если я хочу запустить 30 процессов, это изменение в одну строку.

Есть ли в единицах SystemD параметр, который позволит мне указать, сколько из этих процессов я бы хотел запустить?

Нафтули Кей
источник
1
Вы пытаетесь создать несколько экземпляров одного и того же устройства? Если это так, вы можете посмотреть на 0pointer.de/blog/projects/instances.html
Munir

Ответы:

31

Мунир упомянул, как именно вы это делаете. По сути, вы создаете serviceфайл и запускаете его 30 раз. Теперь это может показаться немного странным, но у него есть свои преимущества, такие как возможность отключить один из них, если он плохо себя ведет, и не нужно закрывать все из них. Есть также некоторые вещи, которые вы можете сделать, чтобы упростить управление.

Сначала файл модуля. Создайте файл, например /etc/systemd/system/test@.service. Важным битом является @символ.

Это содержимое может выглядеть так:

[Service]
ExecStart=/bin/sleep 600 %I

[Install]
WantedBy=multi-user.target

Затем запустите его systemctl start test@1.service, systemctl start test@2.service.
Запущенные процессы будут выглядеть так:

root     17222  19   0  0.0  0.0 Ss         00:05 /bin/sleep 600 1
root     17233  19   0  0.0  0.0 Ss         00:02 /bin/sleep 600 2

Обратите внимание на то, %Iчто вы заменили все, что вы положили после того, @как вы его начали.

Вы можете начать все 30 с небольшим shell-fu:

systemctl start test@{1..30}.service

Вы также можете включить их при загрузке , как и любой нормальный сервис: systemctl enable test@1.service.

 

Теперь, что я имел в виду под вещами, которые вы можете сделать, чтобы упростить управление: возможно, вам не нужно использовать их test@{1..30}.serviceдля управления ими. Это немного громоздко. Вместо этого вы можете создать новую цель для вашего сервиса.

Создать /etc/systemd/system/test.targetс помощью:

[Install]
WantedBy=multi-user.target

Затем настройте /etc/systemd/system/test@.serviceтак, чтобы это выглядело так:

[Unit]
StopWhenUnneeded=true

[Service]
ExecStart=/bin/sleep 600 %I

[Install]
WantedBy=test.target

Перезагрузите systemd с помощью systemctl daemon-reload(необходимо, только если вы изменяете файл модуля и не пропустили более раннюю его версию). А теперь включите все сервисы, которыми вы хотите управлять systemctl enable test@{1..30}.service.
(Если вы ранее включили службу, пока она была WantedBy=multi-user.target, сначала отключите ее, чтобы очистить зависимость)

Теперь вы можете сделать systemctl start test.targetи systemctl stop test.target, и он запустит / остановит все 30 процессов.
И опять же , вы можете включить при загрузке , как и любой другой файл модуля: systemctl enable test.target.

Патрик
источник
Спасибо за этот подробный ответ, я искал это в течение нескольких дней.
Арнолем
1
Вы знаете, если это перезапустит процессы, которые терпят неудачу?
Бастиан
@ Бастиан: вы можете использовать Restart=on-failure. Прочитайте systemd.serviceсправочную страницу для получения дополнительной информации.
Сирида
1

Вот мой пример использования скрипта Python, который выполняется в virtualenv:

/etc/systemd/system/my-worker@.service

[Unit]
Description=manages my worker service, instance %i
After=multi-user.target

[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
Restart=always
TimeoutStartSec=10
RestartSec=10

Отключить: sudo systemctl enable my-worker\@{1..30}.service

Включить N работников: sudo systemctl enable my-worker\@{1..2}.service

Reload: sudo systemctl daemon-reload

Начало: sudo systemctl start my-worker@2.service

Проверь состояние: sudo systemctl status my-worker@1

radtek
источник