Ich muss ein PHP-Skript als Daemon-Prozess ausführen (auf Anweisungen warten und Dinge tun). Cron Job wird es für mich nicht tun, da Maßnahmen ergriffen werden müssen, sobald die Anweisung eintrifft. Ich weiß, dass PHP aufgrund von Speicherverwaltungsproblemen nicht wirklich die beste Option für Daemon-Prozesse ist, aber aus verschiedenen Gründen muss ich in diesem Fall PHP verwenden. Ich bin auf ein Tool von libslack namens Daemon ( http://libslack.org/daemon ) gestoßen, das mir bei der Verwaltung von Daemon-Prozessen zu helfen scheint, aber in den letzten 5 Jahren gab es keine Updates. Ich frage mich, ob Sie welche kennen andere Alternativen für meinen Fall geeignet. Alle Informationen werden sehr geschätzt.
154
Antworten:
Sie können Ihr PHP-Skript über die Befehlszeile (dh Bash) mit starten
nohup php myscript.php &
Das
&
stellt Ihren Prozess in den Hintergrund.Bearbeiten:
Ja, es gibt einige Nachteile, aber nicht möglich zu kontrollieren? Das ist einfach falsch.
Ein einfaches
kill processid
wird es aufhalten. Und es ist immer noch die beste und einfachste Lösung.quelle
nohup
und&
macht genau das Gleiche: den gestarteten Prozess von der aktuellen Intance der Shell zu lösen. Warum brauche ich beide? Kann ich nicht einfach machenphp myscript.php &
odernohup myscript.php
?? Dankenohup php myscript.php > myscript.log &
Eine weitere Option ist die Verwendung von Upstart . Es wurde ursprünglich für Ubuntu entwickelt (und wird standardmäßig mitgeliefert), ist jedoch für alle Linux-Distributionen geeignet.
Dieser Ansatz ähnelt Supervisord und daemontools , da der Daemon beim Systemstart automatisch gestartet und beim Abschluss des Skripts erneut gestartet wird.
So richten Sie es ein:
Erstellen Sie eine neue Skriptdatei unter
/etc/init/myphpworker.conf
. Hier ist ein Beispiel:Starten und Stoppen Ihres Daemons:
Überprüfen Sie, ob Ihr Daemon ausgeführt wird:
Vielen Dank
Ein großes Dankeschön an Kevin van Zonneveld , von dem ich diese Technik gelernt habe.
quelle
sudo service myphpworker start/stop/status
nur mit Diensten funktioniert, die/etc/init.d
nicht in Upstart-Diensten enthalten sind. @ matt-sich scheint die richtige Syntax aufgedeckt zu haben. Eine andere Option ist die Verwendung von Gearman oder Resque, die Hintergrundverarbeitung und Desamonisierung ermöglicht.Mit new systemd können Sie einen Service erstellen.
Sie müssen eine Datei oder einen Symlink in erstellen
/etc/systemd/system/
, z. myphpdaemon.service und platzieren Sie Inhalte wie diesen, myphpdaemon ist der Name des Dienstes:Mit dem Befehl können Sie die Dienste starten, abrufen, neu starten und stoppen
systemctl <start|status|restart|stop|enable> myphpdaemon
Das PHP-Skript sollte eine Art "Schleife" haben, um weiter ausgeführt zu werden.
Arbeitsbeispiel:
Wenn Ihre PHP-Routine einmal in einem Zyklus ausgeführt werden soll (wie ein Diggest), sollten Sie ein Shell- oder Bash-Skript verwenden, um anstelle von PHP direkt in die systemd-Dienstdatei aufgerufen zu werden, zum Beispiel:
Wenn Sie diese Option gewählt haben, sollten Sie den KillMode in
mixed
Prozesse ändern , Bash (Haupt) und PHP (Kind) werden beendet.This method also is effective if you're facing a memory leak.
quelle
systemctl status <your_service_name> -l
Ausgabe überprüfen , sie gibt Ihnen einen Hinweis darauf, was passiert.Wenn Sie können - holen Sie sich eine Kopie der erweiterten Programmierung in der UNIX-Umgebung . Das gesamte Kapitel 13 ist der Daemon-Programmierung gewidmet. Beispiele sind in C, aber alle Funktionen, die Sie benötigen, haben Wrapper in PHP (im Grunde die Erweiterungen pcntl und posix ).
Mit wenigen Worten: Das Schreiben eines Daemons (dies ist nur unter * nix-basierten Betriebssystemen möglich - Windows verwendet Dienste) sieht folgendermaßen aus:
umask(0)
an, um Berechtigungsprobleme zu vermeiden.fork()
und lassen Sie die Eltern beenden.setsid()
.SIGHUP
(normalerweise wird dies ignoriert oder verwendet, um dem Dämon zu signalisieren, seine Konfiguration neu zu laden) undSIGTERM
(um den Prozess anzuweisen, ordnungsgemäß zu beenden).fork()
wieder und lassen Sie die Eltern beenden.chdir()
.fclose()
stdin
,stdout
Undstderr
und schreiben Sie nicht zu ihnen. Der richtige Weg ist, diese entweder/dev/null
oder in eine Datei umzuleiten , aber ich konnte in PHP keinen Weg finden, dies zu tun. Wenn Sie den Daemon starten, ist es möglich, sie mithilfe der Shell umzuleiten (Sie müssen selbst herausfinden, wie das geht, ich weiß nicht :).Da Sie PHP verwenden, achten Sie auch auf zyklische Referenzen, da der PHP-Garbage Collector vor PHP 5.3 keine Möglichkeit hat, diese Referenzen zu sammeln, und der Prozess Speicherverlust verursacht, bis er schließlich abstürzt.
quelle
Ich verwende eine große Anzahl von PHP-Daemons.
Ich stimme Ihnen zu, dass PHP nicht die beste (oder sogar eine gute) Sprache dafür ist, aber die Daemons teilen Code mit den webbasierten Komponenten, sodass es insgesamt eine gute Lösung für uns ist.
Wir verwenden dafür Daemontools. Es ist intelligent, sauber und zuverlässig. Tatsächlich verwenden wir es, um alle unsere Dämonen auszuführen.
Sie können dies unter http://cr.yp.to/daemontools.html überprüfen .
BEARBEITEN: Eine kurze Liste der Funktionen.
quelle
Sie können
nohup
wie Henrik vorgeschlagen hat.screen
Ihr PHP-Programm und führen Sie es als regulären Prozess aus. Dies gibt Ihnen mehr Kontrolle als die Verwendungnohup
.Ich würde die einfachste Methode empfehlen (Bildschirm meiner Meinung nach) und dann, wenn Sie mehr Features oder Funktionen wünschen, zu komplexeren Methoden übergehen.
quelle
Es gibt mehr als einen Weg, um dieses Problem zu lösen.
Ich kenne die Einzelheiten nicht, aber vielleicht gibt es eine andere Möglichkeit, den PHP-Prozess auszulösen. Wenn Sie beispielsweise den Code zum Ausführen basierend auf Ereignissen in einer SQL-Datenbank benötigen, können Sie einen Trigger einrichten, um Ihr Skript auszuführen. Dies ist unter PostgreSQL ganz einfach: http://www.postgresql.org/docs/current/static/external-pl.html .
Ehrlich gesagt denke ich, dass Ihre beste Wette darin besteht, einen Damon-Prozess mit nohup zu erstellen. Mit nohup kann der Befehl auch nach dem Abmelden des Benutzers weiter ausgeführt werden:
Es gibt jedoch ein sehr ernstes Problem. Wie Sie sagten, ist der Speichermanager von PHP ein vollständiger Müll. Er wurde unter der Annahme erstellt, dass ein Skript nur einige Sekunden lang ausgeführt wird und dann vorhanden ist. Ihr PHP-Skript verwendet bereits nach wenigen Tagen GIGABYTES des Speichers. Sie MÜSSEN AUCH ein Cron-Skript erstellen, das alle 12 oder vielleicht 24 Stunden ausgeführt wird und Ihr PHP-Skript wie folgt beendet und erneut erzeugt:
Aber was ist, wenn das Drehbuch mitten in einem Job war? Nun, kill -3 ist ein Interrupt, das gleiche wie Strg + C auf der CLI. Ihr PHP-Skript kann diesen Interrupt abfangen und mithilfe der PHP-PCNL-Bibliothek ordnungsgemäß beenden: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php
Hier ist ein Beispiel:
Die Idee hinter der $ lock ist, dass das PHP-Skript eine Datei mit einem fopen ("file", "w") öffnen kann. Nur ein Prozess kann eine Schreibsperre für eine Datei haben. Mit dieser Option können Sie sicherstellen, dass nur eine Kopie Ihres PHP-Skripts ausgeführt wird.
Viel Glück!
quelle
Kevin van Zonneveld hat einen sehr schönen ausführlichen Artikel dazu geschrieben . In seinem Beispiel verwendet er das
System_Daemon
PEAR-Paket (letztes Erscheinungsdatum am 02.09.2009).quelle
Überprüfen Sie https://github.com/shaneharter/PHP-Daemon
Dies ist eine objektorientierte Daemon-Bibliothek. Es bietet integrierte Unterstützung für Protokollierung und Fehlerbehebung sowie Unterstützung für die Erstellung von Hintergrundarbeitern.
quelle
Vor kurzem brauchte ich eine plattformübergreifende Lösung (Windows, Mac und Linux) für das Problem, PHP-Skripte als Daemons auszuführen. Ich habe das Problem gelöst, indem ich meine eigene C ++ - basierte Lösung geschrieben und Binärdateien erstellt habe:
https://github.com/cubiclesoft/service-manager/
Volle Unterstützung für Linux (über Sysvinit), aber auch Windows NT-Dienste und Mac OSX Launchd.
Wenn Sie nur Linux benötigen, funktionieren einige der anderen hier vorgestellten Lösungen gut genug und je nach Geschmack. Es gibt heutzutage auch Upstart und Systemd, die auf Sysvinit-Skripte zurückgreifen. Die Hälfte der Verwendung von PHP besteht jedoch darin, dass es plattformübergreifend ist, sodass in der Sprache geschriebener Code eine gute Chance hat, überall so zu arbeiten, wie er ist. Mängel treten auf, wenn bestimmte Aspekte des externen nativen Betriebssystems wie Systemdienste in das Bild eingehen. Bei den meisten Skriptsprachen tritt dieses Problem jedoch auf.
Der Versuch, Signale zu fangen, wie es hier im PHP-Userland vorgeschlagen wurde, ist keine gute Idee. Lesen Sie die Dokumentation
pcntl_signal()
sorgfältig durch und Sie werden schnell feststellen, dass PHP Signale mit einigen eher unangenehmen Methoden (insbesondere „Ticks“) verarbeitet, die eine Reihe von Zyklen für etwas zerkauen, das von Prozessen selten gesehen wird (dh Signale). Die Signalverarbeitung in PHP ist auch auf POSIX-Plattformen kaum verfügbar und die Unterstützung unterscheidet sich je nach PHP-Version. Es klingt zunächst nach einer anständigen Lösung, ist aber nicht wirklich nützlich.PHP hat sich im Laufe der Zeit auch in Bezug auf Speicherverlustprobleme verbessert. Sie müssen immer noch vorsichtig sein (der DOM-XML-Parser neigt dazu, immer noch zu lecken), aber ich sehe heutzutage selten außer Kontrolle geratene Prozesse und der PHP-Bug-Tracker ist im Vergleich zu früher ziemlich leise.
quelle
Wie andere bereits erwähnt haben, ist das Ausführen von PHP als Daemon recht einfach und kann mit einer einzigen Befehlszeile erfolgen. Das eigentliche Problem besteht jedoch darin, es am Laufen zu halten und zu verwalten. Ich hatte vor einiger Zeit das gleiche Problem und obwohl es bereits viele Lösungen gibt, haben die meisten viele Abhängigkeiten oder sind schwierig zu verwenden und nicht für grundlegende Verwendungen geeignet. Ich habe ein Shell-Skript geschrieben, das jeden Prozess / jede Anwendung verwalten kann, einschließlich PHP-CLI-Skripten. Es kann als Cronjob zum Starten der Anwendung festgelegt werden und enthält die Anwendung und verwaltet sie. Wenn es erneut ausgeführt wird, beispielsweise über denselben Cronjob, prüft es, ob die App ausgeführt wird oder nicht. Wenn dies der Fall ist, wird es einfach beendet und die vorherige Instanz kann die Anwendung weiter verwalten.
Ich habe es auf github hochgeladen und kann es gerne verwenden: https://github.com/sinasalek/EasyDeamonizer
EasyDeamonizer
Überwacht einfach Ihre Anwendung (Starten, Neustarten, Protokollieren, Überwachen usw.). Ein generisches Skript, um sicherzustellen, dass Ihre Anwendung weiterhin ordnungsgemäß ausgeführt wird. Absichtlich wird der Prozessname instread der PID / Lock-Datei verwendet, um alle Nebenwirkungen zu vermeiden und das Skript so einfach und schnell wie möglich zu halten, sodass es auch dann immer funktioniert, wenn EasyDaemonizer selbst neu gestartet wird. Eigenschaften
quelle
Erweitern Sie die Antwort von Emil Ivaov . Sie können Folgendes tun, um STDIN, STDOUT UND STDERROR in PHP zu schließen
Grundsätzlich schließen Sie die Standard-Streams, damit PHP keinen Platz zum Schreiben hat. Die folgenden
fopen
Aufrufe setzen die Standard-E / A auf/dev/null
.Ich habe dies aus dem Buch von Rob Aley - PHP jenseits des Webs gelesen
quelle
Ich habe einen einfachen PHP-Daemon geschrieben und bereitgestellt, Code ist hier online
https://github.com/jmullee/PhpUnixDaemon
Funktionen: Löschen von Berechtigungen, Signalverarbeitung, Protokollierung
Ich habe es in einem Warteschlangen-Handler verwendet (Anwendungsfall: Auslösen einer längeren Operation von einer Webseite, ohne dass die seitengenerierende PHP warten muss, dh eine asynchrone Operation starten) https://github.com/jmullee/PhpIPCMessageQueue
quelle
Sie können pm2 hier überprüfen, http://pm2.keymetrics.io/
Erstellen Sie eine SSH-Datei, z. B. worker.sh, die in Ihr PHP-Skript eingefügt wird, mit dem Sie sich befassen werden.
worker.sh
Daemon starten
Prost, das ist es.
quelle