Run php script as daemon process

后端 未结 14 1457
-上瘾入骨i
-上瘾入骨i 2020-11-22 11:36

I need to run a php script as daemon process (wait for instructions and do stuff). cron job will not do it for me because actions need to be taken as soon as instruction arr

相关标签:
14条回答
  • 2020-11-22 12:08

    Kevin van Zonneveld wrote a very nice detailed article on this, in his example he makes use of the System_Daemon PEAR package (last release date on 2009-09-02).

    0 讨论(0)
  • 2020-11-22 12:09

    I recently had a need for a cross-platform solution (Windows, Mac, and Linux) to the problem of running PHP scripts as daemons. I solved the problem by writing my own C++ based solution and making binaries:

    https://github.com/cubiclesoft/service-manager/

    Full support for Linux (via sysvinit), but also Windows NT services and Mac OSX launchd.

    If you just need Linux, then a couple of the other solutions presented here work well enough and, depending on the flavor. There is also Upstart and systemd these days, which have fallbacks to sysvinit scripts. But half of the point of using PHP is that it is cross-platform in nature, so code written in the language has a pretty good chance of working everywhere as-is. Deficiencies start showing up when certain external native OS-level aspects enter the picture such as system services, but you'll get that problem with most scripting languages.

    Attempting to catch signals as someone here suggested in PHP userland is not a good idea. Read the documentation on pcntl_signal() carefully and you will quickly learn that PHP handles signals using some rather unpleasant methods (specifically, 'ticks') that chew up a bunch of cycles for something rarely seen by processes (i.e. signals). Signal handling in PHP is also only barely available on POSIX platforms and support differs based on the version of PHP. It initially sounds like a decent solution but it falls pretty short of being truly useful.

    PHP has also been getting better about memory leak issues as time progresses. You still have to be careful (the DOM XML parser tends to leak still) but I rarely see runaway processes these days and the PHP bug tracker is pretty quiet by comparison to the days of yore.

    0 讨论(0)
  • 2020-11-22 12:11

    If you can - grab a copy of Advanced Programming in the UNIX Environment. The entire chapter 13 is devoted to daemon programming. Examples are in C, but all the function you need have wrappers in PHP (basically the pcntl and posix extensions).

    In a few words - writing a daemon (this is posible only on *nix based OS-es - Windows uses services) is like this:

    1. Call umask(0) to prevent permission issues.
    2. fork() and have the parent exit.
    3. Call setsid().
    4. Setup signal processing of SIGHUP (usually this is ignored or used to signal the daemon to reload its configuration) and SIGTERM (to tell the process to exit gracefully).
    5. fork() again and have the parent exit.
    6. Change the current working dir with chdir().
    7. fclose() stdin, stdout and stderr and don't write to them. The corrrect way is to redirect those to either /dev/null or a file, but I couldn't find a way to do it in PHP. It is possible when you launch the daemon to redirect them using the shell (you'll have to find out yourself how to do that, I don't know :).
    8. Do your work!

    Also, since you are using PHP, be careful for cyclic references, since the PHP garbage collector, prior to PHP 5.3, has no way of collecting those references and the process will memory leak, until it eventually crashes.

    0 讨论(0)
  • 2020-11-22 12:12

    Extending Emil Ivaov answer, You can do the following to close STDIN, STDOUT AND STDERROR in php

    if (!fclose(STDIN)) {
        exit("Could not close STDIN");
    }
    
    if (!fclose(STDOUT)) {
        exit("Could not close STDOUT");
    }
    
    if (!fclose(STDERR)) {
        exit("Could not close STDERR");
    }
    
    $STDIN = fopen('/dev/null', 'r');
    $STDOUT = fopen('/dev/null', 'w');
    $STDERR = fopen('/var/log/our_error.log', 'wb');
    

    Basically you close the standard streams so that PHP has no place to write. The following fopen calls will set the standard IO to /dev/null.

    I have read this from book of Rob Aley - PHP beyond the web

    0 讨论(0)
  • 2020-11-22 12:13

    You can

    1. Use nohup as Henrik suggested.
    2. Use screen and run your PHP program as a regular process inside that. This gives you more control than using nohup.
    3. Use a daemoniser like http://supervisord.org/ (it's written in Python but can daemonise any command line program and give you a remote control to manage it).
    4. Write your own daemonise wrapper like Emil suggested but it's overkill IMO.

    I'd recommend the simplest method (screen in my opinion) and then if you want more features or functionality, move to more complex methods.

    0 讨论(0)
  • 2020-11-22 12:18

    you can check pm2 here is, http://pm2.keymetrics.io/

    create a ssh file, such as worker.sh put into your php script that you will deal with.

    worker.sh

    php /path/myscript.php
    

    daemon start

    pm2 start worker.sh
    

    Cheers, that is it.

    0 讨论(0)
提交回复
热议问题