Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So verwalten Sie serverseitige Prozesse mit MySQL

Anscheinend versuchen Sie, Prozesse mit langer Laufzeit von einem Webserver aus zu starten und diese Prozesse dann in einer Datenbank zu verfolgen. Das ist nicht unmöglich, aber keine empfohlene Vorgehensweise.

Das Hauptproblem besteht darin, dass eine HTTP-Anforderung derzeit in Ihrem Webserver verarbeitet werden muss, da Sie dies tun irgendetwas (einschließlich der Verfolgung von Prozessen, die auf dem System laufen) -- Sie brauchen etwas, das die ganze Zeit laufen kann...

Stattdessen wäre es eine bessere Idee, einen anderen dämonisierten "Manager" -Prozess (wie Sie Perl erwähnen, das wäre eine gute Sprache, um ihn zu schreiben) zu haben, um die lang laufenden Aufgaben zu erzeugen und zu verfolgen (durch PID und Signale) und dafür um Ihre SQL-Datenbank zu aktualisieren.

Sie können dann Ihren "Manager"-Prozess auf Anfragen zum Starten eines neuen Prozesses von Ihrem Webserver warten lassen. Es gibt verschiedene IPC-Mechanismen, die Sie verwenden könnten. (zB:Signale, SysV shm, Unix-Domain-Sockets, prozessinterne Warteschlangen wie ZeroMQ usw.).

Dies hat mehrere Vorteile:

  • Wenn Ihre erstellten Skripte mit benutzer-/gruppenbasierter Isolierung (entweder vom System oder untereinander) ausgeführt werden müssen, muss Ihr Webserver weder als root ausgeführt noch als setgid ausgeführt werden.
  • Wenn ein erzeugter Prozess "abstürzt", wird ein Signal an den "Manager"-Prozess geliefert, damit dieser Fehlausführungen ohne Probleme nachverfolgen kann.
  • Wenn Sie prozessinterne Warteschlangen (z. B. ZeroMQ) verwenden, um Anforderungen an den „Manager“-Prozess zu übermitteln, kann dieser Anforderungen vom Webserver „drosseln“ (so dass Benutzer nicht absichtlich oder versehentlich D.O.S. verursachen können).
  • Unabhängig davon, ob der generierte Prozess gut endet oder nicht, Sie benötigen keine "aktive" HTTP-Anforderung an den Webserver, um Ihre Tracking-Datenbank zu aktualisieren.

Ob etwas das sollte be running is running, das hängt wirklich von Ihrer Semantik ab. (d. h.:basiert es auf einer bekannten Laufzeit? basiert es auf verbrauchten Daten? usw.).

Die Prüfung, ob es ist Laufen kann zweifach sein:

  1. Der "Manager"-Prozess aktualisiert die Datenbank nach Bedarf, einschließlich der erzeugten PID.
  2. Ihr vom Webserver gehosteter Code kann tatsächlich Prozesse auflisten, um festzustellen, ob die PID in der Datenbank tatsächlich ist läuft, und sogar, wie lange es etwas Nützliches getan hat!

Die Überprüfung, ob es nicht ist Laufen müsste auf Konvention basieren:

  1. Benennen Sie die erzeugten Prozesse nach etwas, das Sie vorhersagen können.
  2. Erhalten Sie eine Prozessliste, um festzustellen, was noch läuft (nicht mehr funktioniert?), was nicht laufen sollte.

In beiden Fällen können Sie entweder die Benutzer informieren, die das Spawnen der Prozesse angefordert haben, und/oder tatsächlich etwas dagegen unternehmen.

Ein Ansatz könnte darin bestehen, einen CRON-Job zu haben, der aus der SQL-Datenbank liest und ps ausführt um festzustellen, welche erzeugten Prozesse neu gestartet werden müssen, und fordert dann erneut an, dass der "Manager"-Prozess dies unter Verwendung desselben IPC-Mechanismus tut, der vom Webserver verwendet wird. Wie Sie Starts und Neustarts in Ihrem Tracking/Monitoring/Logging unterscheiden, liegt ganz bei Ihnen.

Wenn der Server selbst Strom verliert oder abstürzt, können Sie den "Manager"-Prozess beim ersten Start bereinigen lassen, z. B.:

  1. Suchen Sie in der Datenbank nach Einträgen für erzeugte Prozesse, die angeblich ausgeführt wurden, bevor der Server heruntergefahren wurde.
  2. Prüfen Sie diese Prozesse nach PID und Laufzeit (Das ist wichtig).
  3. Spawnen Sie entweder die gespawnten Prozesse, die nicht abgeschlossen wurden, erneut oder speichern Sie etwas in der Datenbank, um dem Webserver anzuzeigen, dass dies der Fall war.

Aktualisierung Nr. 1

Gemäß Ihrem Kommentar sind hier einige Hinweise für den Einstieg:

Sie haben Perl erwähnt, also vorausgesetzt, Sie haben einige Kenntnisse darin -- hier sind einige Perl-Module, die Ihnen auf dem Weg zum Schreiben des "Manager"-Prozessskripts helfen:

Falls Sie noch nicht damit vertraut sind CPAN ist das Repository für Perl-Module, die im Grunde alles können.

Daemon::Daemonize - Um den Prozess zu dämonisieren, damit er weiter ausgeführt wird, nachdem Sie sich abgemeldet haben. Bietet auch Methoden zum Schreiben von Skripten zum Starten/Stoppen/Neustarten des Daemons.

Proc::Spawn - Hilft beim "Spawnen" von untergeordneten Skripten. Im Grunde funktioniert fork() dann exec() , verarbeitet aber auch STDIN/STDOUT/STDERR (oder sogar tty) des untergeordneten Prozesses. Sie könnten dies verwenden, um Ihre langlaufenden Perl-Skripte zu starten.

Wenn Ihr Webserver-Front-End-Code nicht bereits in Perl geschrieben ist, benötigen Sie etwas, das ziemlich portabel ist, um Nachrichten zwischen Prozessen weiterzuleiten und in Warteschlangen einzureihen. Ich würde wahrscheinlich Ihr Webserver-Frontend in etwas einfach zu implementierendem (wie PHP) machen.

Hier sind zwei Möglichkeiten (es gibt viele mehr):

Proc::ProcessTable - Sie können diese Überprüfung auf laufende Prozesse anwenden (und wie oben beschrieben alle Arten von Statistiken abrufen).

Time::HiRes - Verwenden Sie die Zeitfunktionen mit hoher Granularität aus diesem Paket, um Ihr „Drosselungs“-Framework zu implementieren. Beschränken Sie im Grunde nur die Anzahl der Anfragen, die Sie pro Zeiteinheit aus der Warteschlange entfernen.

DBI (mit mysql ). ) - Aktualisieren Sie Ihre MySQL-Datenbank über den "Manager"-Prozess.