9

What is the best way to keep a PHP script running as a daemon, and what's the best way to check if needs restarting.

I have some scripts that need to run 24/7 and for the most part I can run them using nohup. But if they go down, what's the best way to monitor it so it can be automatically restarted?

Jeff Atwood
  • 63,320
  • 48
  • 150
  • 153
Aldie
  • 819
  • 1
  • 11
  • 16
  • The best and only way is process supervising. It revolves around parent process forking a child and catching its exit signal. If the exit signal isn't good, restart the child process. If a child dies, the parent (supervisor) will restart it. All of the answers provided for this question are bad at best, seeing not a single one mentions a supervisor. – N.B. Aug 18 '14 at 19:46

8 Answers8

5

The most elegant solution is reactPHP.

Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196
  • I think this is the most optimal solution where you can handle everything using just PHP and library like https://github.com/WyriHaximus/reactphp-cron can help you achieve this easily – Muhammad Mar 02 '20 at 12:21
4

If you can't use the (proper) init structure to do this (you're on shared hosting, etc.), use cron to run a script (it can be written in whatever language you like) every few minutes that checks to see if they're running, and restarts them if necessary.

rmmh
  • 6,997
  • 26
  • 37
  • Can you elaborate on what "use[ing] the (proper) init structure to do this" is and how this would solve the issue of ensuring the script is running? – Jonah Braun Sep 22 '08 at 13:35
3

We run our daemons by piping the output to mail.

php daemon.php | mail -s "daemon stopped" foo@example.org

That way, when/if the daemon stops, it will send a mail, and we will be notified that way.

It still means manual restart of the daemons of course, but we'll know right away. Usually, if the daemons stopped, it means that there is something else that needs to be taken care of anyway, so that's usually ok.

troelskn
  • 115,121
  • 27
  • 131
  • 155
3

Quick and dirty cron to restart your daemon:

* * * * * USER ps auxww | grep SCRIPTNAME > /dev/null || SCRIPTNAME

Replace USER with the user that the daemon runs as and SCRIPTNAME with the name of your script. Stick this in /etc/cron.d/restart_php_daemon. It should run every minute. Change the first * to */2 or */5 to run less frequently.

UPDATE

If you're putting this into your own crontab:

Run crontab -e and add:

* * * * * ps auxwww | grep SCRIPTNAME > /dev/null || SCRIPTNAME
Gary Richardson
  • 16,081
  • 10
  • 53
  • 48
  • This looks like a really handy idiom, but I'm not sure this works on mac osx and/or if you don't have root access. Do you have an equivalent for an entry in a user's own crontab file? – dreeves Feb 08 '09 at 05:23
  • When I run "ps auxwww | grep meh" on the command line it returns: --- usersname 2803 0.0 0.0 61156 724 pts/0 SN+ 06:19 0:00 grep meh --- If that cron indeed works, how does it work? Is that not the output from cron? – joedevon Oct 04 '12 at 13:24
  • You're not trying to get the output of ps.. that's why you redirect it to /dev/null. grep is checking for the presence of SCRIPTNAME in the ps output. If it's there, it returns 0, otherwise non-zero. The || SCRIPTNAME will only execute if the grep returns non-zero, which starts the command. – Gary Richardson Oct 05 '12 at 14:40
1

Daemon is a linux process that runs in background; apache or mysql are daemons. In a linux environment, we can run a background program using cronjob, but it has some limitations, and in some scenarios it' s not a good idea. For example, using cronjob, we can't control if the previously run has finished yet. So often it's more convenient run a process as a daemon.

// Daemonize
$pid = pcntl_fork(); // parent gets the child PID and child gets 0
if($pid){ // if pid is not 0
     // Only the parent will know the PID. Kids aren't self-aware
     // Parent says goodbye!
     print "Parent : " . getmypid() . " exiting\n";
     exit();
}
print "Child : " . getmypid() . "\n";

The code above is taken from very good article about how to create a daemon in php. You can read this at link

sergioska
  • 325
  • 5
  • 18
1

I've had success with running a wget and sending the result to /dev/null on a shared server.

Daniel
  • 1,155
  • 1
  • 10
  • 15
0

I use a PHP-based script to read from a database and send emails out (using the PEAR Mail_Queue library). I run it from within a bash script and based on the returned result (from "exit $status;") either halt, sleep X seconds, or immediately restart. (I also put a check of the load average/sleep into the PHP script to avoid stressing the mail system).

If it was for a long-term daemon that had to be continually running, then I agree, it probably would not be the best thing to run this (though I have heard of some socket servers that did run successfully long term), however, PHP 5.3 does also now have improved garbage collection, and if the script is well written enough to not exit unplanned, then memory should be far less of a problem that before.

Alister Bulman
  • 34,482
  • 9
  • 71
  • 110
-1

TBH, PHP probably isn't the best tool for this, really not what it was designed for. I've heard of memory leaks and other bad things happening when you try this. Also bear in mind PHP only has a finite amount of resource ids (for file handles, db connections ect) per execution of a script.

Be better of using something else, maybe python or perl, though I don't have any real experience writing these sorts of apps, but I do know PHP isn't right for what your trying to do.

Robin Barnes
  • 13,133
  • 15
  • 44
  • 45
  • Without trying to sound rude, you should delete this answer, it demonstrates huge level of misinformation and lack of knowledge. "finite amount of resource ids" are handled by operating system, not by PHP. Therefore any other language would have the exact same limitation. Seeing that PHP uses the same library for process control as C language, you could elaborate why it isn't the right tool for it, seeing you have exact same power at your disposal as with C. I understand the dislike for a particular language, but I can never understand deliberate misinformation spread.. – N.B. Aug 18 '14 at 19:44