Этот вопросвозможно, это связано с тем, о чем я здесь спрашиваю.
Это в контекстеhttps://github.com/bstarynk/helpcovid/(программное обеспечение GPLv3+ для Linux, в настоящее время -апрель 2020 г. - вактивныйразработка, которая представляет собой специализированное многопоточное веб-приложение C++ для Linux, поэтомуработа в процессе8 апреля 2020 г.)
Я арендую VPS на хосте b-star-y.tech
под управлением Linux/Debian/Buster.
Я развиваюсь вместе с другимиhelpcovid, многопоточное веб-приложение GPLv3+, написанное для Linux на языке C++17.
Я не знаком сsystemd
, который используется Debian/Buster на этом хосте, или сdocker
Я хотел бы реализоватьследующий бесконечный циклв git clone
дереве файлов d.
git pull
make
- запустить
./helpcovid -D -T2
с перенаправлением stderr и stdout в некоторый файл. sleep 5
иповторять бесконечно.
Я испытываю искушение использоватькронтабработа, или, может быть, atd
сbatch
Есть ли лучший способ сsystemd
?
Вы можете написать мне по электронной почте[email protected]
решение1
Уже около четверти века у нас есть наборы инструментов, которые позволяют непривилегированным пользователям запускать службы nonce по мере необходимости. daemontools Дэниела Дж. Бернстайнаявляется одним из самых ранних. Один неиметьдля настройки сканирования каталогов и другой инфраструктуры. Можно просто запустить программу подsupervise
напрямую. Набор инструментов UCSPI-TCP М. БернстайнаКроме того, это пример нескольких наборов инструментов, которые у нас есть уже в течение аналогичного периода времени и которые обслуживают службы, которым необходимо принимать TCP-соединения и выполнять другие действия.
Существуют и другие наборы инструментов, которые делают то же самое, без необходимости использования systemd, и, конечно, с помощью systemd можнотакженастраивать специальные службы для каждого пользователя.
На дворе 2020 год. Нет никаких веских причин писать новые программы, которые используют шаткий и опасный механизм PID-файлов. Нет никакой необходимости в коде PID-файлов, который вы написали.
Аналогично, хорошей идеей будет написать TCP-сервер, который сможетнаследоватьего прослушивающий сокет, как уже открытый файловый дескриптор. Это на самом деле способ, которымобщесистемныйслужбы, запущенные из inted, традиционно работали с 1980-х годов. Это можно сделать и с помощью per-user служб. Наборы инструментов s6 и nosh, и, конечно, systemd, предоставляют способы, с помощью которых службе может быть предоставлен ее прослушивающий сокет. Нет необходимости влюбойтого кода анализа URL-адреса nonce, который вы написали, который, как и многие импровизированные парсеры, не обрабатывает все формы, которые может принимать URL-адрес.
К сожалению, как я уже сказал, в вашей cpp-httplib
библиотеке нет конструктора или функционального члена, где это можно было бы сделать.данныйдескриптор файла для прослушиваемого сокета. Это серьезная оплошность в дизайне этой библиотеки, учитывая, что наследование дескрипторов файлов сокетов было обычной практикой в течение трех с небольшим десятилетий.
что-нибудьКроме каксистемд
Обамой набор инструментов для едыиНабор инструментов s6 Лорана Беркопредоставляют способы запуска программ nonce в качестве специальных служб для каждого пользователя.
В наборе инструментов nosh будет helpcovid
подкаталог, а service
в нем — подкаталог, содержащий различные программы для управления сервисом.
helpcovid/service/start
и helpcovid/service/stop
довольно минимальны:
#!/bin/nosh
#Start file generated from ./helpcovid.socketand ./helpcovid.service
true
#!/bin/nosh
#Stop file generated from ./helpcovid.socketand ./helpcovid.service
true
Мясо внутри helpcovid/service/run
и helpcovid/service/service
:
#!/bin/nosh
#Run file generated from ./helpcovid.socketand ./helpcovid.service
#Starynkevitch helpcovid listening socket
tcp-socket-listen --systemd-compatibility ::0 50002
envdir env
setenv LC_ALL fr_FR.UTF-8
chdir /home/basile/dev/helpcovid/test
./service
#!/bin/nosh
#Service file generated from ./helpcovid.service
#Starynkevitch helpcovid service
sh -c 'exec /home/basile/dev/helpcovid/work/helpcovid ${flags}'
И helpcovid/service/restart
управляет логикой перезапуска:
#!/bin/sh
#Restart file generated from ./helpcovid.service
sleep 5
exec true # ignore script arguments
Этот будет запущен путем передачи его экземпляру пользователя service-manager
. Набор инструментов выполняет привязку и прослушивание сокета, считывает конфигурацию переменных среды из envdir и передает открытый файловый дескриптор конечной программе с помощью протокола LISTEN_FDS
, изменив рабочий каталог на место, где webroot/
находится ваш тестовый каталог.
Подобная структура используется в s6, хотя названия инструментов отличаются (например,s6-tcpserver6-socketbinder
скорее, чемtcp-socket-listen
) и логика перезапуска обрабатывается по-другому. s6 не требует менеджера служб. Как и оригинальные daemontools, можно просто запуститьs6-supervise
вручную, чтобы вызвать службу:
s6-supervise ./helpcovid/service/
Я не буду вдаваться в подробности, поскольку главное, что отсутствие systemd не является оправданием плохого дизайна демона (на самом деле, принципы хорошего дизайна демонавозникло сгораздо более старые механизмы, не относящиеся к systemd), и что механизмы передачи открытых файловых дескрипторов для прослушивающих сокетов применимы и могут использоваться не только с systemd.
системд
Вышеуказанные программы фактически были преобразованы из systemdблок розетокисервисный блоккоторые я быстро собрал. Они показывают, как можно настроить службу для каждого пользователя на systemd с файлами в ~/.config/systemd/user/
:
# helpcovid.socket
[Unit]
Description=Starynkevitch helpcovid listening socket
[Socket]
ListenStream=50002
Accept=No
[Install]
Wanted-By=default.target
# helpcovid.service
[Unit]
Description=Starynkevitch helpcovid service
[Service]
Environment=LC_ALL=fr_FR.UTF-8
Restart=always
RestartSec=5
ExecStart=/home/basile/dev/helpcovid/work/helpcovid ${flags}
WorkingDirectory=/home/basile/dev/helpcovid/test
#This has no meaning for systemd.
EnvironmentDirectory=env
Это контролируется с помощью таких средств, как systemctl --user start helpcovid.socket
.
В мире systemd этиявляютсяфайлы конфигурации. Пользователь хочет изменить номер порта TCP? Пользователь изменяет настройку ListenStream=
. Нет необходимости в избыточных дополнительных переменных среды для настройки локали. Пользователь просто устанавливает фактическую LC_ALL
(или любую другую) переменную, как показано.
Ведение журнала
Ведение журнала также обрабатывается службой управления. Набор инструментов nosh и способ s6 — это подача стандартного вывода и стандартной ошибки через канал во вторичную службу, работающую cyclog
, s6-log
, или что-то еще. systemd помещает вывод журнала в пользовательскую часть централизованного журнала systemd, который вы используете journalctl --user
для чтения.
ваша программа
Ваша программа должна зарегистрироваться std::clog
(т. е. стандартная ошибка), вызвать setlocale()
с помощью NULL
для чтения стандартных переменных окружения и иметь код, который обрабатывает механизм LISTEN_FDS
. Для последнего есть много вариантов, от непереносимой библиотеки вспомогательных функций, которая идет с systemd, до более переносимых чужих аналогичных решений.
Определенно, это намного меньше кода, чем весь этот код анализа номера порта TCP, шаткий и опасный код файла PID и HELPCOVID_LOCALE
код --locale
, который можно вывести таким образом. ☺
дальнейшее чтение
- Джонатан де Бойн Поллард (2001). Ошибки, которых следует избегать при разработке программ-демонов Unix. Часто задаваемые ответы.
- https://github.com/jdebp/nosh/blob/ddb422c9e6db11aee1c22a171bcc729edc7fe1c3/source/listen.cpp#L1
- Проблемы: