ホームページ  >  記事  >  バックエンド開発  >  グレースフル リスタートを実現するための PHP 高度なプログラミング デーモン プロセス

グレースフル リスタートを実現するための PHP 高度なプログラミング デーモン プロセス

WBOY
WBOYオリジナル
2016-06-23 13:24:221058ブラウズ

PHP Advanced Programming Daemon

http://netkiller.github.io/journal/php.daemon.html

Neo Chen (陈京峰) 氏、netkiller、 7NYT

中国広東省深セン市龍華新区民志街西山美地
518131
+86 13113668890
+86 755 29812080
6e61359cee4f36410cc69c8751705c8cpidfile) によってプログラムは実行されていますが、その後プロセスが強制終了されるため、実行する前にファイルを手動で削除する必要があります

private function daemon(){		if (file_exists($this->pidfile)) {			echo "The file $this->pidfile exists.\n";			exit();		}				$pid = pcntl_fork();		if ($pid == -1) {			 die('could not fork');		} else if ($pid) {			// we are the parent			//pcntl_wait($status); //Protect against Zombie children			exit($pid);		} else {			// we are the child			file_put_contents($this->pidfile, getmypid());			posix_setuid(self::uid);			posix_setgid(self::gid);			return(getmypid());		}	}

プログラムの開始後、親プロセスが起動されますを実行すると、子プロセスがバックグラウンドで実行され、子プロセスの権限が root から指定されたユーザーに切り替えられ、同時にプロセス ID ファイルの書き込みが行われます。

5.2. プログラムが停止します

プログラムは停止し、pid ファイルを読み取り、posix_kill($pid, 9) を呼び出し、最後にファイルを削除します。
private function stop(){		if (file_exists($this->pidfile)) {			$pid = file_get_contents($this->pidfile);			posix_kill($pid, 9); 			unlink($this->pidfile);		}	}

5.3. シングルトン モード

これは、各スレッドがこのデータベース接続を確立および終了する場合に非常に重要であり、データベースに大きなオーバーヘッドが発生します。 。
protected function getInstance(){	return self::$dbh;}

5.4. グレースフル リスタートを実現する

いわゆるグレースフル リスタートとは、プロセスが終了しない状況に加え、変数のリセット、設定ファイルの更新、ログのリセットなどを含むリロードを指します。 /start または、再起動するとプロセスが終了して再起動され、プロセス ID が変更されます。同時に、すぐに終了するとビジネスが中断されます。したがって、多くのデーモン プロセスは、いわゆるグレースフル リスタートであるリロード機能を提供します。 リロードの実装原則は、プロセスに SIGHUP シグナルを送信することです。kill コマンドを使用して kill -s SIGHUP 64881 を送信することも、ライブラリ関数を使用して posix_kill(posix_getpid(), SIGUSR1) を実装することもできます。設定ファイル
<?phppcntl_signal(SIGTERM,  function($signo) {    echo "\n This signal is called. [$signo] \n";    Status::$state = -1;});pcntl_signal(SIGHUP,  function($signo) {    echo "\n This signal is called. [$signo] \n";    Status::$state = 1;	Status::$ini = parse_ini_file('test.ini');});class Status{    public static $state = 0;	public static $ini = null;}$pid = pcntl_fork();if ($pid == -1) {    die('could not fork');}if($pid) {    // parent} else {	$loop = true;	Status::$ini = parse_ini_file('test.ini');    while($loop) {		print_r(Status::$ini);        while(true) {			// Dispatching... 			pcntl_signal_dispatch();			if(Status::$state == -1) {				// Do something and end loop.				$loop = false;				break;			}						if(Status::$state == 1) {				printf("This program is reload.\r\n");				Status::$state = 0;				break;			}            echo '.';            sleep(1);        }        echo "\n";    }        echo "Finish \n";    exit();}

テスト方法、まずデーモンを実行します

[root@netkiller pcntl]# cat test.ini [db]host=192.168.0.1port=3306

次に、設定ファイルを変更して user=test 設定項目を追加します

# php signal.reload.php Array(    [host] => 192.168.0.1    [port] => 3306)

別のターミナル ウィンドウで、ps コマンドを使用して PID を見つけます。プロセスを削除し、kill コマンドを使用して SIGHUP シグナルを送信し、ps でプロセスを確認すると、プロセスの PID が変更されていないことがわかります

うわー

設定ファイルがリロードされました

This signal is called. [1] This program is reload.Array(    [host] => 192.168.0.1    [port] => 3306    [user] => test)

优雅重启完成。

6. 进程意外退出解决方案

如果是非常重要的进程,必须要保证程序正常运行,一旦出现任何异常退出,都需要做即时做处理。下面的程序可能检查进程是否异常退出,如果退出便立即启动。

#!/bin/shLOGFILE=/var/log/$(basename $0 .sh).logPATTERN="my.php"RECOVERY="/path/to/my.php start"while truedo        TIMEPOINT=$(date -d "today" +"%Y-%m-%d_%H:%M:%S")        PROC=$(pgrep -o -f ${PATTERN})        #echo ${PROC}        if [ -z "${PROC}" ]; then		${RECOVERY} >> $LOGFILE                echo "[${TIMEPOINT}] ${PATTERN} ${RECOVERY}" >> $LOGFILE                        #else                #echo "[${TIMEPOINT}] ${PATTERN} ${PROC}" >> $LOGFILE        fisleep 5done &
   
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。