[gelöst] Debian PHP-Script "endlos" laufen lassen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
exxecc
Beiträge: 30
Registriert: 24.07.2010 12:32:29
Lizenz eigener Beiträge: MIT Lizenz

[gelöst] Debian PHP-Script "endlos" laufen lassen

Beitrag von exxecc » 05.09.2012 23:15:54

Hi zusammen!

Momentan haben wir einen minütlichen Cronjob, der ein PHP-Script anwirft welches mittels Lockfile und usleep 57 sekunden läuft.
nach den 57 Sekunden ist also schluss, und der minütliche Cron wirft das Script zur vollen Minute wieder neu an.
Soweit so gut, wenn nicht mittlerweile die Tablelocks in MySQL die Ausführung des Scriptes zeitlich über das Limit blockieren..
Somit kommt das Script auf über 60 Sekunden - der nächste Cronjob wirft das Script wieder an (zweite Instanz), welches anhand der Lockfile bemerkt, dass es noch läuft und sich wieder beendet.
Jetzt sind wir, bei sagen wir 70 Sekunden angekommen und die erste Instanz ist endlich beendet - somit muss jetzt wieder 50 Sekunden auf den neuen Aufruf des Scripts gewartet werden.

Was für Möglichkeiten (Tools, Shellscripts?) gibt es welche ich anwenden kann, um sicherzustellen dass mein php script sofort nach Beendigung wieder angeworfen wird?
Innerhalb PHP würde ich das nur sehr ungern umsetzen, da gibt es dann keine 100%ige Sicherheit (in sachen Ausführung) wie sie zB über Cron gegeben ist. (Bitte nicht an dem Satz aufhängen..)

Grob gefragt: Kennt jemand ein Tool, welches ich über cron minütlich starten kann (erkennt doppelte Ausführung und beendet sich), und den gewünschten Prozess anstößt sobald dieser sich beenden sollte? Das Tool kann auch gerne endlos laufen - Cron also nur als "Sicherheit" hinten dran, um ein "totales Versagen" zu vermeiden.

Klar kann man sowas auch über PHP machen - jede Sekunde checken ob der Prozess noch da ist etc, aber das ist wie ich finde extrem unschön.

Vielen Dank schonmal für die Anregungen.

Viele Grüße
exxecc
Zuletzt geändert von exxecc am 10.09.2012 11:57:58, insgesamt 1-mal geändert.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Debian PHP-Script "endlos" laufen lassen

Beitrag von Cae » 06.09.2012 00:22:25

Code: Alles auswählen

$ while :; do date; sleep 1; done    
Wed Sep  5 23:59:02 CEST 2012
Wed Sep  5 23:59:03 CEST 2012
Wed Sep  5 23:59:04 CEST 2012
Wed Sep  5 23:59:05 CEST 2012
Wed Sep  5 23:59:06 CEST 2012
Wed Sep  5 23:59:07 CEST 2012
Wed Sep  5 23:59:08 CEST 2012
^C
$ 
So etwas? Du musst beachten, dass a) das Skript (hier symbolisiert durch date und sleep 1) nicht keine Zeit verbrauchen darf und b) sich nicht wegforken darf. a) ist kein Widerspruch, das Skript muss Zeit verbrauchen, am Besten einen Gutteil davon, ohne Ressourcen zu brauchen. Andernfalls hättest du eine ungebremste Endlosschleife, und das ist nicht gut. Die ungebremste Endlosschleife ist auch bei Fall b), mit der Spezialität einer zugegebenermaßen ineffizienten [1] Forkbombe.

Gruß Cae

[1] while :; do { sleep 1 & }; done # ist eine lineare Forkbombe, da die Forks (hier sleep) keine weiteren Prozesse wegforkt. Die "Alternative" wäre das klassische :(){:|:};: # – da wird eine Funktion definiert, die sich selbst zwei Mal aufruft. Anschließend wird sie gestartet, damit haben wir einem Prozess, er bildet zwei, macht drei, die beiden rufen jeweils sich selbst zwei Mal auf, macht sieben. Die vier neuesten erzeugen je zwei neue Prozesse, macht 15; wir sind hier erst in der vierten Ebene. Die Prozessanzahl folgt also dem Schema 2^1-1. Für das Zielsystem wollen wir eine vernünftige Konfiguration hoffen, das die Unterprozesse pro Benutzer einschränkt.
Bei der linearen Bombe hat man noch Chancen, den Masterprozess zu killen, bei der exponentiellen forkt es schon nach wenigen Sekunden an allen Ecken und Enden, da kommt man nur mit Limits gegen an.
Und für die Klugscheißer, ja, die Shell forkt nicht unbedingt für jeden Funktionsaufruf einen neuen Prozess raus, aber das frisst halt Ressourcen irgendeiner Art, und zwar eben linear oder exponentiell (oder ein drittes). Ähm, das ist eigentlich eine Fußnote hier, aber mittlerweile fast länger als der Rest vom Post… huch.
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
Phineas
Beiträge: 354
Registriert: 20.06.2012 20:26:19

Re: Debian PHP-Script "endlos" laufen lassen

Beitrag von Phineas » 06.09.2012 04:54:43

Andere Möglichkeit:

Code: Alles auswählen

#!/bin/bash
...
DEIN_PHP_SCRIPT
...
sleep 57s
$0 $@
Ruft sich immer wieder selbst auf (mitsamt Parametern). Auf Leerzeichen in Scriptname und Parametern achten (bzw. diese quoten).

Edit: Sorry, vergiss diesen Selbstaufruf. Der forkt.

exxecc
Beiträge: 30
Registriert: 24.07.2010 12:32:29
Lizenz eigener Beiträge: MIT Lizenz

Re: Debian PHP-Script "endlos" laufen lassen

Beitrag von exxecc » 06.09.2012 09:31:46

Hi

@ Cae
Theoretisch könnte ich das schon nutzen, wenn ich nicht das "selbstaufrufproblem" hätte.
Ich würde das Script gerne per Cron minütlich ansteuern um sicherzustellen dass das "Observe Script" nicht gestorben ist.
Das "Observe Script" muss natürlich erkennen ob es parallel schon läuft, und sich beenden falls ja.

Hier hab ich was gebastelt was funktioniert - was mich aber noch stört ist: da ich das Script per Aufruf in den Hintergrund setze ist der nice lvl auf 19. Kann man das beim Aufruf oder danach abändern?
Gibt es bei dem Script sonst irgendwelche Ungereimtheiten die jemand erkennt?
Mein erstes Shell Script, deshalb die Fragen..

Code: Alles auswählen

#!/bin/bash

# script that should be in cronjob running every minute
# this script will not run trough if it detects itself running parallel
#####

# lockfile
sLockFile='/var/opt/pwatcher/pwatcher.lock'
# sleeptime between check in seconds
iSleep=2
# folder path from where we will execute the script
sFolderPath="/var/opt/myscript/"
# execute script command
sExecuteCommand="./mybinscript"


# check if lockfile exists
if [ -e $sLockFile ]; then
    # another instance is running - bye
    echo 'allready running .. bye ..'
    exit
else
    # create lockfile
    echo $$ > $sLockFile

    # guarantee delete of lockfile on exit
    trap "rm $sLockFile; exit" 0 1 2 3 4 6 8 15 20
fi


# go into script folder
cd $sFolderPath

# check for running scripts
while [ 1 = 1 ]
do
    # check if proccess exists allready
    sProccessID=`pgrep -f -x ".*$sExecuteCommand.*"`

    if [ -z "$sProccessID" ]; then

        $sExecuteCommand &> /var/log/myscript.log &

    fi

    sleep $iSleep
done

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Debian PHP-Script "endlos" laufen lassen

Beitrag von uname » 06.09.2012 10:10:12

Falls du noch Debiansysvinit nutzt könntest du mal versuchen das Script in /etc/inittab über "respawn" einzubinden. Keine Ahnung wie das bei Debianupstart oder Debiansystemd geht und ob es überhaupt sinnvoll ist bzw. funktioniert.

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Debian PHP-Script "endlos" laufen lassen

Beitrag von Cae » 06.09.2012 15:47:33

exxecc hat geschrieben:der nice lvl auf 19. Kann man das beim Aufruf oder danach abändern?
renice(1).
exxecc hat geschrieben:Gibt es bei dem Script sonst irgendwelche Ungereimtheiten die jemand erkennt?
Jepp:
exxecc hat geschrieben:

Code: Alles auswählen

    echo $$ > $sLockFile
# [...]
    # check if proccess exists allready
    sProccessID=`pgrep -f -x ".*$sExecuteCommand.*"`

    if [ -z "$sProccessID" ]; then
Du hast dir doch da oben schon die PID gemerkt, da kannst du auch gucken, ob der Prozess noch läuft. Was funktioniert ist

Code: Alles auswählen

if [ -d "/proc/$(cat "$sLockFile")" ]; then # [...]
– aber das muss irgendwie ohne /proc/ gehen.
exxecc hat geschrieben:

Code: Alles auswählen

    trap "rm $sLockFile; exit" 0 1 2 3 4 6 8 15 20
Elegant! Noch nicht mal Bash-only-Syntax, mir dennoch bisher nahezu unbekannt.
exxecc hat geschrieben:

Code: Alles auswählen

# check for running scripts
while [ 1 = 1 ]
do
Besser:

Code: Alles auswählen

while :; do
: (der Doppelpunkt) ist true und ergibt dasselbe wie test 1 = 1 ([ (eckige Klammer auf) ist test).
exxecc hat geschrieben:

Code: Alles auswählen

        $sExecuteCommand &> /var/log/myscript.log &
Das sieht komisch aus. Ist das der Versuch, stdout und stderr zusammen zu loggen?

Code: Alles auswählen

$sExecuteCommand 2>&1 >>/var/log/myscript.log &
Bitte bei Logs ein gescheites rotate implemetieren (oder logrotate verwenden) und >> anstatt > verwenden. Man überschreibt sich sonst beim erneuten Versuch die Debugmeldungen vom gerade fehlgeschlagenen Versuch. Unschön (ich spreche aus Erfahrung).

Bis auf das trap ist alles garantiert in der (da)sh vorhanden, du bräuchtest also nicht unbedingt die fettere Bash zu nehmen. trap hat möglicherweise eine abweichende Syntax.

Gruß Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

exxecc
Beiträge: 30
Registriert: 24.07.2010 12:32:29
Lizenz eigener Beiträge: MIT Lizenz

Re: Debian PHP-Script "endlos" laufen lassen

Beitrag von exxecc » 10.09.2012 11:57:45

Das sieht komisch aus. Ist das der Versuch, stdout und stderr zusammen zu loggen?
Ja das war es, hab ich mittlerweile auch umgeschrieben auf "2>&1"

Alles andere wurde abgeändert (auch mit prozessid lookup) und funktioniert nun einwandfrei!

Vielen Dank!

Antworten