В моей организации есть несколько рабочих процессов, потребляющих очередь. В настоящее время мы используем SupervisorD для управления ими, но хотели бы использовать SystemD, если это возможно, из-за определенных преимуществ. У меня достаточно опыта в написании пользовательских модулей, но у меня нет аналога в SystemD для этого.
вДокументация SupervisorDпараметр называется numprocs
подробным, который позволяет задать количество процессов, которые они хотели бы запустить с помощью службы. Если я хочу запустить 30 процессов, это изменение в одну строку.
Есть ли настройка в единицах SystemD, которая позволит мне указать, сколько из этих процессов я хочу запустить?
решение1
Мунир упомянул, как именно это делается. По сути, вы создаете service
файл и запускаете его 30 раз. Это может показаться немного громоздким, но у этого есть преимущества, например, возможность закрыть один из них, если он ведет себя неправильно, и не нужно закрывать их все. Есть также некоторые вещи, которые вы можете сделать, чтобы упростить управление.
Сначала файл блока. Создайте файл, например . Важная часть — это символ./etc/systemd/system/[email protected]
@
Его содержимое может выглядеть так:
[Service]
ExecStart=/bin/sleep 600 %I
[Install]
WantedBy=multi-user.target
Затем запустите его с помощью , . Процессы, которые будут запущены, будут выглядеть так:systemctl start [email protected]
systemctl start [email protected]
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 с небольшого ракушечного фу:
systemctl start test@{1..30}.service
Вы также можете включить их при загрузке, как любую обычную службу: .systemctl enable [email protected]
Теперь, что я имел в виду под вещами, которые вы можете сделать, чтобы облегчить управление: Возможно, вы не хотите использовать test@{1..30}.service
для управления ими всеми. Это немного громоздко. Вместо этого вы можете создать новую цель для своей службы.
Создать /etc/systemd/system/test.target
с помощью:
[Install]
WantedBy=multi-user.target
Затем отрегулируйте так, чтобы это выглядело так:/etc/systemd/system/[email protected]
[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
.
решение2
Вот мой пример использования скрипта Python, который работает в virtualenv:
/etc/systemd/system/[email protected]
[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 disable my-worker\@{1..30}.service
Включить N рабочих:sudo systemctl enable my-worker\@{1..2}.service
Перезагрузить:sudo systemctl daemon-reload
Начинать:sudo systemctl start [email protected]
Проверить состояние:sudo systemctl status my-worker@1