Search code examples
linuxdaemonphpapache2.2

Managing php daemon


How can I manage my daemon from the web without changing simple cli runtime to php-fpm?

The daemon starts up automatically after OS starts up and works as cli-application without php-fpm pool. So the basic ideology of daemon eco-system is to work without php-fpm pool (CLI-SAPI).

Server configuration:

  1. Debian 7
  2. Apache 2.2
  3. php5-fpm (v 5.4.35) — mod_fastcgi
  4. daemon.php
  5. daemon_manager.php — Management script for start|stop|restart|kill daemon.php from command line.
  6. daemon_manager_web.php — Administrator script for managing daemon from browser.

daemon.php is a regular php daemon like this:

<?php
    declare(ticks=1);
    ini_set("max_execution_time", "0");
    ini_set("max_input_time",     "0");
    set_time_limit(0);
    /* Catching signals */
    function sig_handler($signo) {
        switch ($signo) {
            case SIGQUIT:
            case SIGTERM:
                // some work
        pcntl_wait($status);
                break;
            //...
        }
    }

    pcntl_signal(SIGTERM, 'signal_handler');
    pcntl_signal(SIGQUIT, 'signal_handler');

    $newpid = pcntl_fork();
    if ($newpid == -1) {
        throw new Exception('Cannot fork porcess');
    } elseif ($newpid) {
        print "Starting daemon under pid=$newpid\n";
        // ...
        exit;
    }

The problem.

Since PCNTL-functions are not available from the Web, I manage daemon by functions such as exec(), shell_exec(). But when I stop and start daemon again using daemon_manager_web.php from browser it normally starts but works under php-fpm pool.

Processes list before restart:

$ ps aux | grep php
root      5952  0.0  2.9  69008 14952 pts/0    S    14:24   0:00 php /var/www/daemon.php

$ service php5-fpm status
php5-fpm.service - LSB: starts php5-fpm
      Loaded: loaded (/etc/init.d/php5-fpm)
      Active: active (running) since Fri, 05 Dec 2014 11:28:25 +0200; 11h ago
     Process: 1003 ExecStart=/etc/init.d/php5-fpm start (code=exited, status=0/SUCCESS)
      CGroup: name=systemd:/system/php5-fpm.service
              ├ 1627 php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
              ├ 9562 php-fpm: pool www
              ├ 9605 php-fpm: pool www
              └ 9633 php-fpm: pool www

Processes list after restart from browser:

$ service php5-fpm status
php5-fpm.service - LSB: starts php5-fpm
      Loaded: loaded (/etc/init.d/php5-fpm)
      Active: active (running) since Fri, 05 Dec 2014 11:28:25 +0200; 11h ago
     Process: 1003 ExecStart=/etc/init.d/php5-fpm start (code=exited, status=0/SUCCESS)
      CGroup: name=systemd:/system/php5-fpm.service
              ├ 1627 php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
              ├ 4987 php-fpm: pool www
              ├ 5040 php-fpm: pool www
              ├ 9432 php-fpm: pool www
              └ 9492 /usr/bin/php /var/www/daemon.php 

Solution

  • You should not start a daemon via Apache in any way. The proper way to do it would be to start a daemon as such (managed by, say, supervisord, I have a pretty good track record using that in production) and opening a file socket (AF_UNIX) on which you do a socket_select() and idle-wait for some input which triggers a processing. That way, the "interface" (on Apache) just connects to the sockets and writes to it.

    On that topic, I've found writing daemons in PHP to be quite tedious and you might want to choose a library to handle the nitty-gritty for you (cannot recommend any) or even another tool more suitable for the event loop typical of daemons (node.js?)