Запускать огромное количество сервисов с помощью systemd

Я хочу запустить огромное количество (например, 256) служб с помощью systemd. К счастью, systemd предлагает срезы, что упрощает повторное использование описания службы. Но запуск многих процессов одновременно убивает систему, потому что каждый процесс выполняет некоторые начальные вычисления, что увеличивает нагрузку выше 50.

Можно ли определить цепочку зависимостей для всех служб с помощью срезов, (скрыто) ( hidden) Или можно определить что-то вроде пула служб, и systemd управляет запуском служб, то есть запускать не все сразу, а запускать сразу 10, а после этого следующий блок?

0
25.04.2017, 22:05
2 ответа

Нет, systemd не поддерживает синтаксис типа Wants=service@%(i-1).service?.

Однако вы можете написать простой сценарий, который выписывает 256 подобных файлов systemd unit, содержащих явную цепочку зависимостей. Вот некоторые другие шаблоны для рассмотрения:

  1. systemd позволяет вам устанавливать параметры управления ресурсами во время выполнения, с синтаксисом вроде:

    systemctl --runtime set-property foobar.service CPUShares=777

Таким образом, вы можете дросселировать ваши устройства во время запуска, чтобы каждое из них использовало меньше CPU, а затем, когда все успокоится, позволить им использовать больше CPU. Это кажется сложнее, чем нужно, что приводит меня к следующему варианту...

  1. В man systemd.resource-control вы найдете, что есть опция StartupCPUShares=, которая отличается от опции CPUShares=. Я бы поэкспериментировал с дросселированием CPU с помощью StartupCPUShares=, чтобы посмотреть, даст ли это желаемый результат.

Лично я использовал очень низкотехнологичный путь для решения подобной проблемы. Я запускал серию служб по одной за раз, с "сном" между запусками служб. Это использовало немного сценариев bash вместо system, но работало достаточно хорошо. К счастью, у меня также нет необходимости запускать все службы как можно быстрее.

Следующую итерацию системы я, вероятно, спроектирую на основе systemd и, возможно, попробую использовать StartupCPUShares=, чтобы посмотреть, не лучше ли это способ решения проблемы.

0
28.01.2020, 02:46

Я нашел хорошее решение, используя ExecStartPost.

% systemctl --user cat example@ 
# /home/joerg/.config/systemd/user/example@.service
[Unit]
Description=Example of service farm; instance %i

[Service]
Type=simple
ExecStart=/bin/sleep 99999
ExecStartPost=/bin/sh -c 'test %i -gt 0 || exit 0 ; systemctl --no-block --user start %p@$((%i - 1))'

% systemctl --user start example@2

% systemctl --user status example.slice
● example.slice
   Loaded: loaded
   Active: active since Thu 2017-04-27 11:04:43 CEST; 27min ago
   CGroup: /user.slice/user-1000.slice/user@1000.service/example.slice
           ├─example@0.service
           │ └─19423 /bin/sleep 99999
           ├─example@1.service
           │ └─19420 /bin/sleep 99999
           └─example@2.service
             └─19417 /bin/sleep 99999
1
28.01.2020, 02:46

Теги

Похожие вопросы