Шрифт:
В основе данной схемы лежит то, что таким важным модулям служб времени загрузки, как syslog и dbus необходимо некоторое время для запуска, а многие другие модули зависят от них. Однако команда systemd способна предоставить важный для модуля ресурс (например, модуль сокета) очень быстро, после чего она может немедленно активизировать не только важный модуль, но также и любые другие модули, которые зависят от данного важного ресурса. Как только важный модуль будет готов, он забирает управление ресурсом.
На рис. 6.2 показано, как такая схема могла бы работать в традиционной системе. В данной последовательности загрузки служба E предоставляет важный ресурс R. Службы A, B и C зависят от этого ресурса и должны ожидать запуска службы E. Во время загрузки такой системе потребуется довольно много времени, чтобы добраться до запуска службы С.
Рис. 6.2. Временн'aя последовательность загрузки. Указана зависимость ресурсов
На рис. 6.3 показана эквивалентная конфигурация загрузки с помощью команды systemd. Службы представлены модулями A, B и C, а новый модуль R представляет ресурс, который предоставляет модуль E. Поскольку команда systemd способна обеспечить интерфейс для модуля R, пока запускается модуль E, модули A, B, C и E могут быть все запущены одновременно. Модуль E заступает на место модуля R, когда будет готов. Интересным моментом здесь является то, что модулям A, B и C может не понадобиться явный доступ к модулю R до завершения их запуска — это демонстрирует на схеме модуль B.
примечание
При подобном распараллеливании запуска есть вероятность того, что система на некоторое время замедлит свою работу вследствие большого количества одновременно стартующих модулей.
В конечном счете, хотя вы и не создаете в данном случае запуск модуля по запросу, вы используете те же функции, которые делают его возможным. Чтобы увидеть примеры из реальной жизни, загляните в модули конфигурации syslog и D-Bus на компьютере, использующем команду systemd; очень возможно, что они будут распараллелены подобным же образом.
Пример модуля сокета и службы
Рассмотрим теперь в качестве примера простую службу сетевого эхо-запроса, которая использует модуль сокета. Этот материал достаточно сложный, и вы, вероятно, сможете понять его только после прочтения глав 9 и 10, в которых рассмотрены протокол TCP, порты, прослушивание и сокеты. По этой причине сейчас можно его пропустить и вернуться к нему позже.
Рис. 6.3. Временн'aя последовательность загрузки с помощью systemd и модуля ресурсов
Идея, заложенная в эту службу, заключается в том, что, когда сетевой клиент подключается к данной службе, она повторяет все, что отправляет клиент. Модуль будет прослушивать TCP порт 22222. Мы назовем его службой эхо-запроса и начнем с модуля сокета, представленного следующим файлом модуля echo.socket:
[Unit]
Description=echo socket
[Socket]
ListenStream=22222
Accept=yes
Обратите внимание на то, что внутри файла модуля нет упоминания о том, какой модуль службы поддерживается данным сокетом. Каков же тогда соответствующий файл модуля службы?
Он называется echo@.service. Эта ссылка составлена на основе соглашения о присвоении имен: если у файла модуля службы такой же префикс, что и у файла .socket (в данном случае echo), команда systemd знает о том, что надо активизировать данный модуль службы, когда в модуле сокета возникает активность. В данном случае команда systemd создает экземпляр echo@.service, когда возникает активность сокета echo.socket.
Вот файл модуля службы echo@.service:
[Unit]
Description=echo service
[Service]
ExecStart=-/bin/cat
StandardInput=socket
примечание
Если вам не нравится неявная активизация модулей на основе префиксов или же вам необходимо создать механизм активизации между двумя модулями с разными префиксами, можно использовать вариант явного присвоения в модуле, который определяет ресурс. Применяйте, например, запись Socket=bar.socket внутри файла foo.service, чтобы модуль bar.socket предоставлял свой сокет службе foo.service.
Чтобы данная служба заработала, необходимо запустить после нее сокет echo.socket:
# systemctl start echo.socket
Теперь можно проверить эту службу, подключившись к локальному порту 22222. Когда приведенная ниже команда telnet установит соединение, наберите что-либо и нажмите клавишу Enter. Служба возвратит вам набранный текст.
$ telnet localhost 22222
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.