Das Upstart-Ereignissystem: Was es ist und wie es verwendet wird

Einführung

Initialization ist ein entscheidendes Verfahren, das jedem Unix-basierten Betriebssystem zugrunde liegt, um den Betrieb jedes Skripts und Dienstes zu steuern. Dies ist in einer Serverumgebung von entscheidender Bedeutung, in der Probleme an den kritischen Punkten beim Starten und Herunterfahren auftreten können und in der die Gewährleistung einer optimalen Leistung Vorrang hat.

Im Wesentlichen folgt die Initialisierung dieser Art von Prozess:

  1. Der Server bootet

  2. Der Prozessinit wird ausgeführt (normalerweise alsPID 1).

  3. Ein vordefinierter Satz von Startaufgaben wird nacheinander aktiviert

Die Initialisierung ist dafür verantwortlich, dass der Cloud-Server ordnungsgemäß gestartet und heruntergefahren werden kann.

Einige Distributionen mit einer Unix-Grundlage verwenden den Standardprozessinitfür die Initialisierung. In diesem Artikel werfen wir einen Blick aufUpstart - einen praktischen und leistungsstarken Ersatz, der den Betrieb Ihres Servers beschleunigen kann.

Was ist los mit dem klassischen init?

Die herkömmliche Initialisierung erfolgt linear: Einzelne Tasks werden beim Systemstart in einer vordefinierten Reihenfolge geladen. Dies ist insbesondere in sich schnell ändernden Situationen nicht hilfreich. Stellen Sie sich zum Verständnis vor, Sie hätten beispielsweise die Serverumgebung durch Hinzufügen eines zusätzlichen Speichergeräts geändert.

Der Initialisierungsprozess kann plötzliche Änderungen in der Umgebung nicht berücksichtigen. Dies bedeutet, dass Ihr Cloud-Server erneut initialisiert werden muss, bevor er den zusätzlichen Speicher erkennt. On-the-Fly-Erkennung ist erforderlich, obwohl es sich nicht um eine klassische Initialisierungsprozedur handelt.

Das Booten in einer linearen Reihenfolge erfordert auch Zeit, was besonders in einer Cloud-basierten Umgebung nachteilig ist, in der eine schnelle Bereitstellung unerlässlich ist.

Möglicherweise sind Sie auch über den Status Ihrer Aufgaben nach dem Laden des Systems besorgt. Leider istinit nur dann mit der Sequenz befasst, wenn Sie hochfahren oder ausschalten.

Synchrone Bootsequenzen sind nicht mehr erwünscht. Ein starres System könnte die Systeme von gestern unterstützen, aber heute ist es dynamisch.

Hier kommtUpstart ins Spiel - eine Lösung für diese Probleme mit erweiterten Funktionen.

Basierend auf den Ereignissen vonreal-timeanstelle einer voreingestellten Liste von Aufgaben nacheinander übernimmt dieser Ersatz-Init-Daemon das Starten und Stoppen von Aufgaben.andüberwacht diese Prozesse, während das System ausgeführt wird - „vollständige Abdeckung“ ist die beste Weg, um es zu beschreiben.

Diese neu asynchrone Verarbeitung macht eine starre Startsequenz überflüssig. Die Echtzeitverarbeitung ist zwar schwierig zu konzipieren, aber Upstart kann die komplexesten Systeme unterstützen und mithilfe einer Struktur vonjobs alles in Schach halten.

Ein Überblick über Upstart

Upstart Logo

Das von Anfang an flexibel gestaltete Upstart-Ereignissystem verwendet eine Vielzahl von Konzepten, die sich von herkömmlichen Initialisierungssystemen unterscheiden. Die Lösung ist standardmäßig auf Red Hat Enterprise Linux (RHEL) 6 sowie auf Googles Chrome OS und Ubuntu installiert, obwohl die jüngste Debatte zu Unklarheiten darüber geführt hat, ob dies fortgesetzt wird.

Jobs

In der Welt von Upstart sind Jobs Arbeitsprozesse, die in Task-Jobs (mit Zweck) und Service-Jobs (die im Hintergrund ausgeführt werden können) unterteilt sind. Es gibt auch abstrakte Jobs - Prozesse, die für immer ausgeführt werden, bis sie von einem Benutzer mit Administratorrechten angehalten werden.

Veranstaltungen

Events sind jedoch die Signale oder "Aufrufe", die verwendet werden, um eine bestimmte Aktion mit einem Job oder einem anderen Ereignis auszulösen. Die häufigsten Formen von Ereignissen beziehen sich auf die Überwachung eines Prozesses:starting,started,stopping undstopped.

Ereignisse senden

Der Vorgang des Sendens eines Ereignisses wird als "Senden" bezeichnet. Dies wird normalerweise durch einen Prozess- oder Jobstatus verursacht. Ein Administrator kann ein Ereignis jedoch auch manuell ausgeben, indem er den Befehlinitctl emit <event> ausgibt. Sie werden feststellen, dass der Befehlinit controlunglaublich nützlich ist, wenn Sie durch die Vielzahl der mit Upstart verbundenen Vorgänge navigieren.

Schreiben Ihrer ersten Jobkonfiguration

Es ist bekannt, dass Upstart unter Ubuntu eine gute Leistung erbringt. Drehen Sie also einUbuntu 14.04 Droplet hoch, bevor Sie beginnen.

Nun, da Sie bereit sind, ist es wichtig zu verstehen, dass eine Auftragskonfigurationsdatei drei Grundprinzipien erfüllen muss, um gültig zu sein.

  • Es darf nicht leer sein (eine Datei ohne Inhalt)

  • Es darf keine Syntaxfehler enthalten

  • Es muss mindestens einen Befehlsblock enthalten, der alsstanza bezeichnet wird

Lassen Sie es uns zunächst einfach halten. In Kürze erstellen wir eine Datei mit dem Namentestjob.conf im Verzeichnis/etc/init. In diesem Fall wird "init" nur als verkürzte Version von "initialization" verwendet.

Beachten Sie die Dateizuordnung von.conf, die angibt, dass Siejob configuration file schreiben.

Für die Zwecke dieses Lernprogramms wird der Befehlszeilentexteditornano empfohlen. Für einige dieser Befehle sind möglicherweise Administratorrechte mitsudo erforderlich. Überprüfen Sie daherthis article, um einen geeigneten Benutzer zu erstellen.

Führen Sie Folgendes aus, um eine neue Konfigurationsdatei für unseren Testjob zu erstellen:

sudo nano /etc/init/testjob.conf

Lassen Sie uns nun das Ziel skizzieren. Wir möchten, dass dieser Jobwrite a message and the current timestamp to a log file beträgt.

Es gibt zwei grundlegende Zeilengruppen, mit denen Sie den Zweck eines Jobskripts definieren und festlegen können, wer es erstellt hat:description undauthor. Schreiben Sie diese als erste Zeilen in die Datei.

description "A test job file for experimenting with Upstart"
author "Your Name"

Jetzt möchten wir, dass dieser Job ausgeführt wird, nachdem die Systemdienste und -prozesse bereits geladen wurden (um Konflikte zu vermeiden), sodass in Ihrer nächsten Zeile das folgende Ereignis enthalten ist:

start on runlevel [2345]

Sie fragen sich vielleicht, was ein Runlevel ist. Im Wesentlichen handelt es sich um einen einzelnen Wert, der die aktuelle Systemkonfiguration darstellt. [2345] bezieht sich auf alle Konfigurationszustände mit allgemeinem Linux-Zugriff und Netzwerk, was ideal für ein grundlegendes Testbeispiel ist.

Wir werden dann den Ausführungscode hinzufügen. Diese Zeile beginnt mitexec, um anzugeben, dass die folgenden Befehle über die Bash-Shell ausgeführt werden sollen:

exec echo Test Job ran at  `date` >> /var/log/testjob.log

Beachten Sie, dass dieser Befehlecho Backticks verwendet, umdate als Befehl auszuführen und dann die gesamte Nachricht in eine Protokolldatei zu schreiben. Wenn Sie das Wortdate ohne Backticks geschrieben haben, wird das Wort selbst anstelle der Ausgabe des Befehls gedruckt.

Speichern und schließen Sie diese Datei.

Sie können überprüfen, ob dies funktioniert, indem Sie den Job manuell starten. Überprüfen Sie jedoch zuerst die Syntax der Konfigurationsdatei:

init-checkconf /etc/init/testjob.conf

Wenn Probleme festgestellt werden, gibt dieser Befehl die spezifische Zeilennummer und das Problem an. Beim Testjob sollte die Ausgabe jedoch so aussehen:

File /etc/init/testjob.conf: syntax ok

Dieser Befehl kann zum Steuern von Upstart-Jobs und anderen Hintergrunddiensten wie einem Webserver verwendet werden.

Die grundlegende Befehlssyntax lautet:

sudo service  

Diese Syntax funktioniert mit den folgenden grundlegenden Steuerelementen:

  • Neustart: Dies stoppt und startet einen Dienst

  • start: Hiermit wird ein Dienst gestartet, wenn er nicht ausgeführt wird

  • stop: Hiermit wird ein Dienst angehalten, falls er ausgeführt wird

  • status: Zeigt den Status eines Dienstes an

Wir möchten unseren Testjob manuell starten, daher sollte der Befehl folgendermaßen aussehen:

sudo service testjob start

Überprüfen Sie nun dietestjob.log-Datei, indem Sie den folgenden Befehl ausführen:

cat /var/log/testjob.log

Dieser Befehl liest die Datei in die Shell aus. Sie sollten eine einzelne Zeile sehen, die der folgenden ähnlich ist:

Test Job ran at Fri Aug 1 08:43:05 BST 2014

Dies zeigt, dass Ihr Testjob eingerichtet und einsatzbereit ist.

Starten Sie Ihr Droplet neu, melden Sie sich an und lesen Sie die Protokolldatei erneut:

cat /var/log/testjob.log

In der zweiten Zeile des Protokolls sollte ein späterer Zeitstempel angezeigt werden, um zu bestätigen, dass es als Upstart-Job ausgeführt wurde.

Test Job ran at Fri Aug 1 08:44:23 BST 2014

Dies zerkratzt lediglich die Oberfläche dessen, was Sie mit Upstart tun können. Wir werden später auf ein detailliertes Beispiel eingehen. Lassen Sie uns jedoch vorerst mit der Erläuterung der Auftragszustände und Ereignisse fortfahren.

Arbeitszustände und Ereignisse

Systemjobs befinden sich im Verzeichnis/etc/init/, und Benutzerjobs befinden sich im eigenen Init-Verzeichnis des Benutzers,~/.init/.

Benutzerjobs werden in der eigenen Sitzung des Benutzers ausgeführt. Sie werden daher auch als Sitzungsjobs bezeichnet. Diese werden nicht systemweit ausgeführt und sind nicht in der BezeichnungPID 1enthalten. Für unseren Testjob haben wir/etc/init verwendet, damit es beim Booten des Systems geladen werden kann.

Unabhängig von seinem Typ ist ein Jobalways, der in einer Konfigurationsdatei (.conf) definiert ist, in der sein Dateiname den betreffenden Dienst oder die betreffende Aufgabe darstellen soll.

Jeder dieser Jobs hat ein Ziel -start oderstop. Zwischen diesen beiden Zielen befinden sich eine Reihe von Aufgabenzuständen, die die aktuellen Aktionen des Auftrags in Bezug auf das Ziel definieren. Die wichtigen Zustände sind wie folgt:

  • Warten: Der Ausgangszustand der Verarbeitung

  • Starting: Wo ein Job anfangen soll

  • Pre-Start: Hier wird der Pre-Start-Bereich geladen

  • Spawned: Wo ein Skriptabschnitt ausgeführt werden soll

  • Nachstart: Hier finden Nachstartoperationen statt

  • Laufen: Wo der Job voll funktionsfähig ist

  • Pre-Stop: Hier finden Vor-Stopp-Vorgänge statt

  • Anhalten: Wo der Job angehalten wird

  • getötet: wo der Job gestoppt wird

  • post-stop: wo post-stop Operationen stattfinden - um aufzuräumen

Nach dem Status nach dem Start wird der Job als ausgeführt definiert. Es läuft weiter, bis ein Pre-Stop ausgelöst wird, wo der Job zum Stoppen bereit wird, dann der Job beendet wird und die Prozeduren nach dem Stoppcleanuptattfinden, falls definiert.

Sie können anzeigen, wie ein Job zwischen Status wechselt, indem Sie mit diesem Befehl die Priorität des Upstart-Systemprotokolls (im Verzeichnis/var/log/upstart/) aufdebug setzen:

sudo initctl log-priority debug

Denken Sie daran, dassstates are not events, and events are not states. Die vier Ereignisse (Starten, Starten, Stoppen und Stoppen) werden von Upstart ausgegeben, aber die Task-Zustände definieren den Übergang zwischen den Lebensphasen eines Jobs.

Wir sind jetzt bereit, ein fokussierteres Beispiel zu erstellen, das Elemente aus Ihrer allerersten Konfiguration enthält, indem Sie einen Serviceauftrag schreiben. Hier wird gezeigt, wie Sie vom Ausführen grundlegender Testkonfigurationen zu produktionsfertigen Skripten übergehen können.

Ausführliches Beispiel: Ein Service-Job

Ein Service-Job, der in der Einführung kurz behandelt wird, umfasst das Erstellen von Skripts für Konfigurationsdateien, mit denen Prozesse im Hintergrund ausgeführt werden können. Wir werden einbasic Node.js server von Grund auf neu einrichten.

Wenn Sie mit Node nicht vertraut sind, handelt es sich im Wesentlichen um eine "plattformübergreifende Umgebung für serverseitige Anwendungen und Netzwerkanwendungen" (Wikipedia).

Node.js is a very lightweight package, although it isn’t installed by default on Ubuntu 14.04. Installieren Sie es zunächst auf Ihrem Cloud-Server.

sudo apt-get install nodejs

Beginnen wir jetzt mit dem Service-Job. Erstellen Sie eine neue Jobkonfigurationsdatei in/etc/init mit dem Namennodetest.conf. Die Benennung der Datei in Bezug auf ihren Zweck ist unerlässlich, damit Sie erkennen können, dass dieser Service-Job für einen Node.js-Test bestimmt ist.

sudo nano /etc/init/nodetest.conf

Wir werden später in diesem Beispiel auf die Node-Anwendung selbst eingehen, da es wichtig ist, die Upstart-Konfiguration im Voraus zu verstehen.

Das wichtigste zuerst. Beginnen Sie mit der Eingabe der Jobbeschreibung und der Autorenzeile, um die Konfiguration zu definieren.

description "Service for a test node.js server"
author      "Your Name"

Wir möchten, dass diese Serveranwendung mit Knoten gestartet wird, wenn der Server in Betrieb ist, und beendet wird, wenn er ordnungsgemäß heruntergefahren wird. Stellen Sie aus diesem Grund sicher, dass Sie beide Bedingungen angeben:

start on filesystem or runlevel [2345]
stop on shutdown

Erinnern Sie sich an die Runlevel-Kriterien von früher? In Kombination mit dem Ereignisfilesystemwird so sichergestellt, dass der Job geladen wird, wenn der Server normal läuft.

Das sind die Grundlagen, aber jetzt wird es komplizierter; Wir werden die zuvor erwähntenstanzasverwenden.

Da es sich um eine Serveranwendung handelt, wird ein Protokollierungselement in die Auftragskonfiguration aufgenommen. Da wir protokollieren möchten, wann die Knotenanwendung gestartet und gestoppt wird, verwenden wir drei verschiedene Zeilengruppen, um unsere Serviceaktionen zu trennen:script,pre-start script undpre-stop script.

Wenn Ihnen das bekannt vorkommt, haben Sie absolut Recht. Pre-Start und Pre-Stop sind Jobzustände, sie funktionieren aber auch in Strophen. Dies bedeutet, dass je nach Status des Jobs verschiedene Befehle ausgeführt werden können.

Die erste Zeilengruppe, die geschrieben wird, ist das Jobskript selbst. Dadurch wird eine Prozess-ID für den Node-Hintergrundserver abgerufen und anschließend das Anwendungsskript ausgeführt. Beachten Sie die Einrückung von Befehlen in einer Zeilengruppe - dies ist für die syntaktisch korrekte Formatierung unerlässlich.

script

    export HOME="/srv"
    echo $$ > /var/run/nodetest.pid
    exec /usr/bin/nodejs /srv/nodetest.js

end script

Für den Knoten muss eine Ausgangsverzeichnisvariable festgelegt werden, weshalb/srv in die erste Zeile der Zeilengruppe exportiert wird. Als nächstes wird$$ verwendet, um eine verfügbare Prozess-ID abzurufen und eine PID-Datei für unseren Job zu erstellen. Danach wird die Node.js-Anwendung geladen, die wir später schreiben werden.

Es ist jetzt an der Zeit, sich aufpre-start undpre-stop zu konzentrieren, die für unsere einfache Anwendungsprotokollierung verwendet werden. Das Datum wird zusammen mit einer Start- oder Stoppmeldung an eine Protokolldatei für unseren Job angehängt:

pre-start script
    echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script

Beachten Sie, dass die Zeilengruppe "Pre-Stop" eine weitere Zeile enthält: Entfernen der PID-Datei als Teil der Prozedur zum Herunterfahren des Servers (was Pre-Stop bewirkt).

pre-stop script
    rm /var/run/nodetest.pid
    echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script

Das ist die gesamte Konfiguration des Upstart-Jobs. Hier ist das Ganze noch einmal als Referenz:

description "Test node.js server"
author      "Your Name"

start on filesystem or runlevel [2345]
stop on shutdown

script

    export HOME="/srv"
    echo $$ > /var/run/nodetest.pid
    exec /usr/bin/nodejs /srv/nodetest.js

end script

pre-start script
    echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script

pre-stop script
    rm /var/run/nodetest.pid
    echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script

Speichern und schließen Sie die Datei.

Wie in der Zeileexec angegeben, wird ein Node.js-Skript vom Server ausgeführt. Erstellen Sie daher einenodetest.js-Datei an Ihrem gewünschten Speicherort (/srv/ wird für dieses Beispiel verwendet):

sudo nano /srv/nodetest.js

Da es sich um ein Upstart-Lernprogramm handelt, werden wir den Code von Node.j nicht zu lange durcharbeiten. Im Folgenden finden Sie jedoch einen Überblick über die Funktionen dieses Skripts:

  • HTTP-Modul des Knotens anfordern und laden

  • Erstellen Sie einen HTTP-Webserver

  • Geben Sie im Header eine Status 200-Antwort (OK) ein

  • Schreiben Sie als Ausgabe „Hello World“

  • Hören Sie auf Port 8888

Hier ist der Code, den Sie benötigen, um die Node-Anwendung zum Laufen zu bringen. Er kann direkt kopiert werden, um Zeit zu sparen:

var http = require("http");

http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
}).listen(8888);

Nach dem Speichern der Datei Node.js muss als Letztes überprüft werden, ob die Syntax des Upstart-Jobs gültig ist. Führen Sie wie gewohnt den Konfigurationsprüfbefehl aus und Sie sollten eine Bestätigung als Ausgabe erhalten:

init-checkconf /etc/init/nodetest.conf

File nodetest.conf: syntax ok

Sie haben Ihre Jobkonfiguration erhalten, die Syntax überprüft und Ihren Node.js-Code gespeichert. Alles ist einsatzbereit. Starten Sie also Ihr Droplet neu und besuchen Siehttp://IP:8888 oder die zugehörige Domäne.

Wenn Sie in der oberen linken Ecke des Fensters auf "Hello World" gestoßen sind, hat der Upstart-Service-Job funktioniert!

Lesen Sie zur Bestätigung der zustandsbasierten Protokollierung die vordefinierte Protokolldatei, und Sie sollten eine Zeile mit dem ZeitstempelStarting sehen. Wenn Sie den Server herunterfahren oder den Dienstjob manuell stoppen, wird eineStopping-Zeile in das Protokoll geschrieben, die Sie auch überprüfen können, wenn Sie dies wünschen.

cat /var/log/nodetest.log

[Sun Aug 17 08:08:34 EDT 2014] Node Test Starting
[Sun Aug 17 08:13:03 EDT 2014] Node Test Stopping

Sie können Standardstart, -stopp, -neustart usw. ausführen. Befehle für diesen Dienst und ähnliche Upstart-Jobs mit der folgenden Syntax:

sudo service nodetest restart

Fazit

In diesem Lernprogramm wird nur die Oberfläche des Upstart-Ereignissystems zerkratzt. Sie haben den Hintergrund der herkömmlichen Initialisierung gelesen, herausgefunden, warum die Open-Source-Upstart-Lösung eine leistungsfähigere Wahl ist, und begonnen, eigene Jobs zu schreiben. Jetzt, da Sie die Grundlagen kennen, sind die Möglichkeiten endlos.

Logo von der offiziellen Upstart-Website, Copyright-Originaldesigner / Canonical Ltd.