Diese Fragehängt vielleicht mit der Frage zusammen, die ich hier frage.
Dies ist im Kontext vonhttps://github.com/bstarynk/helpcovid/(eine GPLv3+ Software für Linux, derzeit - April 2020 - inaktivEntwicklung, eine spezialisierte C++ Multithread-Webanwendung für Linux, alsoin Arbeitam 8. April 2020)
Ich miete einen VPS auf einem Host, b-star-y.tech
auf dem Linux/Debian/Buster läuft.
Ich entwickle mich mit anderenHilfeCovid, eine mehrfädige GPLv3+-Webanwendungssoftware, die für Linux in C++17 codiert ist.
Ich bin nicht vertraut mitsystemd
, das von Debian/Buster auf diesem Host verwendet wird, oder mitdocker
Ich möchte umsetzendie folgende Endlosschleifein einem git clone
D-Dateibaum.
git pull
make
- Wird ausgeführt
./helpcovid -D -T2
, wobei sowohl stderr als auch stdout zu einer Datei umgeleitet werden. sleep 5
Undunendlich wiederholen.
Ich bin versucht, einecrontabJob oder vielleicht atd
mitbatch
Gibt es mit einen besseren Weg systemd
?
Sie können mir eine E-Mail senden an[email protected]
Antwort1
Seit etwa einem Vierteljahrhundert verfügen wir über Toolsets, die es nicht privilegierten Benutzern ermöglichen, Nonce-Dienste ad hoc auszuführen. Daemontools von Daniel J. Bernsteinist einer der frühesten. Manhabenum Scan-Verzeichnisse und andere Infrastruktur einzurichten. Man kann einfach ein Programm untersupervise
direkt. M. Bernsteins UCSPI-TCP-Toolsetist darüber hinaus ein Beispiel für die verschiedenen Tool-Sets, die wir seit ähnlicher Zeit haben und die Dienste handhaben, die TCP-Verbindungen annehmen und Dinge tun müssen.
Es gibt andere Toolsets, die dasselbe tun, ohne dass systemd erforderlich ist, und natürlich kann man mit systemdAuchRichten Sie Ad-hoc-Dienste pro Benutzer ein.
Wir schreiben das Jahr 2020. Es gibt keinen guten Grund, neue Programme zu schreiben, die den wackeligen und gefährlichen PID-Dateimechanismus verwenden. Der PID-Dateicode, den Sie geschrieben haben, wird überhaupt nicht benötigt.
Ebenso ist es eine gute Idee, einen TCP-Server zu schreiben, damit diesererbensein Listening-Socket als bereits geöffneter Dateideskriptor. Dies ist in der Tat die Art und Weise, wiesystemweitDienste, die von inted ausgeführt werden, werden seit den 1980er Jahren konventionell betrieben. Dies kann auch mit benutzerspezifischen Diensten durchgeführt werden. Die Toolsets s6 und nosh sowie systemd bieten alle Möglichkeiten, einem Dienst seinen Listening-Socket zuzuweisen. Es besteht keine Notwendigkeit fürbeliebigdes von Ihnen geschriebenen Nonce-URL-Analysecodes, der wie viele spontane Parser nicht alle Formen einer URL verarbeiten kann.
Leider hat Ihre Bibliothek, wie gesagt, cpp-httplib
keinen Konstruktor oder Funktionsmember, wo esgegebender Dateideskriptor für den Listening-Socket. Dies ist ein großes Versäumnis beim Entwurf dieser Bibliothek, da die Vererbung von Socket-Dateideskriptoren seit über drei Jahrzehnten gängige Praxis ist.
etwasaußersystemd
Beidemein Nosh-ToolsetUndLaurent Bercots S6-Werkzeugsatzbieten Möglichkeiten, Nonce-Programme als Ad-hoc-Dienste pro Benutzer auszuführen.
Unter dem Nosh-Toolset gäbe es ein helpcovid
Unterverzeichnis und service
darunter ein Unterverzeichnis, das die verschiedenen Programme zur Handhabung des Dienstes enthält.
helpcovid/service/start
und helpcovid/service/stop
sind ziemlich minimal:
#!/bin/nosh
#Start file generated from ./helpcovid.socketand ./helpcovid.service
true
#!/bin/nosh
#Stop file generated from ./helpcovid.socketand ./helpcovid.service
true
Das Fleisch ist drin helpcovid/service/run
und 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}'
Und helpcovid/service/restart
steuert die Neustartlogik:
#!/bin/sh
#Restart file generated from ./helpcovid.service
sleep 5
exec true # ignore script arguments
Dieses würde ausgeführt, indem es einer pro Benutzer vorhandenen Instanz von übergeben wird service-manager
. Das Toolset übernimmt die Bindung und Überwachung des Sockets, liest die Umgebungsvariablenkonfiguration aus einem envdir und übergibt den offenen Dateideskriptor unter Verwendung des LISTEN_FDS
Protokolls an das endgültige Programm, nachdem das Arbeitsverzeichnis an den Ort geändert wurde, an dem sich Ihr Testverzeichnis webroot/
befindet.
Eine ähnliche Struktur wird in s6 verwendet, allerdings sind die Werkzeugnamen unterschiedlich (z. B.s6-tcpserver6-socketbinder
statttcp-socket-listen
) und die Neustartlogik wird anders gehandhabt. s6 erfordert keinen Service-Manager. Wie bei den ursprünglichen Daemontools kann man einfach ausführens6-supervise
per Hand, um einen Dienst aufzurufen:
s6-überwachen ./helpcovid/service/
Ich werde nicht zu sehr ins Detail gehen, da der Hauptpunkt ist, dass das Fehlen von systemd keine Entschuldigung für schlechtes Dæmon-Design ist (in der Tat sind gute Dæmon-Designprinzipienentstand mitviel ältere Nicht-Systemd-Mechanismen) und dass die Mechanismen zum Übergeben offener Dateideskriptoren für Abhör-Sockets für mehr als nur Systemd gelten und mit mehr davon verwendet werden können.
systemd
Die oben genannten Programme wurden tatsächlich von einem systemd konvertiertSteckdoseneinheitUndServiceeinheitdie ich schnell zusammengewürfelt habe. Sie zeigen, wie man einen benutzerspezifischen Dienst auf systemd einrichtet, mit Dateien in ~/.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
Dies wird mit Leuten wie gesteuert systemctl --user start helpcovid.socket
.
In der Welt von systemdSinddie Konfigurationsdateien. Der Benutzer möchte die TCP-Portnummer ändern? Der Benutzer ändert die ListenStream=
Einstellung. Es sind keine redundanten zusätzlichen Umgebungsvariablen zum Festlegen des Gebietsschemas erforderlich. Der Benutzer legt einfach die tatsächliche LC_ALL
(oder eine beliebige) Variable auf die gezeigte Weise fest.
Protokollierung
Die Protokollierung wird ebenfalls von der Dienstverwaltung übernommen. Die Methode des Nosh-Toolsets und von S6 besteht darin, die Standardausgabe und den Standardfehler über eine Pipe an einen sekundären Dienst weiterzuleiten cyclog
, s6-log
auf dem , , oder etwas Ähnliches ausgeführt wird. systemd füllt die Protokollausgabe in den Benutzerteil des zentralisierten systemd-Journals, das Sie journalctl --user
zum Lesen verwenden.
Ihr Programm
Ihr Programm muss sich anmelden std::clog
(d. h. Standardfehler), setlocale()
mit aufrufen NULL
, um die Standardumgebungsvariablen zu lesen, und Code haben, der den LISTEN_FDS
Mechanismus handhabt. Für Letzteres gibt es viele Möglichkeiten, von einer nicht portablen Hilfsfunktionsbibliothek, die mit systemd geliefert wird, bis hin zu portableren Workalikes anderer Leute.
Es muss auf jeden Fall weitaus weniger Code eingefügt werden als der ganze TCP-Portnummern-Analysecode, der wackelige und gefährliche PID-Dateicode und HELPCOVID_LOCALE
der --locale
Code, der auf diese Weise entfernt werden kann. ☺
Weiterführende Literatur
- Jonathan de Boyne Pollard (2001). Zu vermeidende Fehler beim Entwurf von Unix-Dämon-Programmen. Häufig gestellte Fragen.
- https://github.com/jdebp/nosh/blob/ddb422c9e6db11aee1c22a171bcc729edc7fe1c3/source/listen.cpp#L1
- Probleme: