PHPプログラムをデーモン起動する(CentOS)

PHPで作成したプログラムをデーモン化しサービス起動させる場合には、デーモン化対応した「PHPプログラム」とそれを起動する「起動スクリプト」の2種類を用意する必要がある。

PHPプログラム

PHPプログラムでは、まず自プロセスをfork/execし端末から切り離し、実行中のプログラムをPIDファイルに書き込む。そのあと自分のプロセスをセッションリーダに指定する処理を行う。

<?php
// pid fileの生成
$pidfile = "/var/run/hoged/hoged.pid";
// 全てのエラー出力をOFF
error_reporting(0);
// 子プロセスの生成
$pid = pcntl_fork();
if($pid < 0){
        // 失敗時
        exit();
}else if($pid){
        // 親プロセスの終了
        exit();
}else{
        // pidファイルを生成
        $pid = getmypid();
        $fp = fopen($pidfile, "w");
        @fwrite( $fp, $pid, strlen($pid) );
        fclose($fp);
        // 現在のプロセスをセッションリーダにする
        $sid = posix_setsid();
        if($sid<0){
                // 失敗時
                exit();
        }
        // ループ処理
        while(TRUE){
                //////////////////////////
                //      定期処理       //
                /////////////////////////
        }
}
?>

起動スクリプト

起動スクリプトは、/etc/rc.d/init.dに設置される各デーモンの起動や終了を行うスクリプトである。/etc/init.d/skeletonもしくは/usr/share/doc/initscripts-*/sysvinitfilesにサンプルが存在する。スクリプト内chkconfigの欄は、RunLevel, 起動時のPriority, 終了時のPriorityの順に記述する。PIDを置くディレクトリは事前にmkdirしておく必要がある。

#!/bin/bash
#
# hoged                Startup script for the Hoge System
#
# chkconfig: 345 99 01
# descroption: The Hoge System.
# processname: hoged
#

# Source function library.
. /etc/init.d/functions

# Path to the script
hoged=/home/hoge/hoged.php
prog=hoged
pidfile=${PIDFILE-/var/run/hoged/hoged.pid}
lockfile=${LOCKFILE-/var/lock/subsys/hoged}
RETVAL=0

start() {
        if [ -f $lockfile ]; then
        echo "$prog is Started"
        exit 1
        fi

        echo -n "Starting $prog: "
        daemon --pidfile=${pidfile} --user hoge php $hoged
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}       

stop() {
        echo -n "Shutting down $prog: "
        killproc -p ${pidfile} $hoged
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status -p ${pidfile} $hoged
        RETVAL=$?
        ;;
    restart)
        stop
            start
        ;;
    *)
        echo "Usage: $prog {start|stop|status}"
        exit 1
        ;;
esac
exit $RETVAL