一、 進程守護使用場景。
后端經常會有類似這樣的場景,某個腳本,需要不斷的重復運行,這個時候,最好有一個守護程序,幫助我們不斷地自動地拉起這些腳本進程,讓它自動地重復運行。在 Linux/Unix 系統下,supervisor 就是使用 python 開發的一個優秀的進程管理工具,本文嘗試使用 php 來實現類似的進程管理工具。
二、swoole 的進程管理模塊。
php 的 swoole 擴展有一個進程管理模塊
參考 supervisor 的實現方式,被守護的進程是作為 supervisor 的子進程來啟動的,supervisor 通過監聽子進程的信號,可實現對子進程的自動重啟等功能。
而 swoole 的進程管理模塊就提供了進程間通信的功能,可以實現對子進程的自動重啟功能。
三、第一個進程守護程序。
要實現對子程序的守護,需要做到兩點:
程序需要監聽到子進程的結束信號,以便于重新拉起新的子進程。
子進程的運行環境需要獨立于父進程。
swoole 進程管理模塊提供了一個 bool Process->exec (string $execfile, array $args) 方法,讓子進程蛻變成另一個系統調用程序,同時還能保證父進程與當前進程仍然是父子進程關系。
再通過 array Process::wait (bool $blocking = true) 方法,來等待子進程的退出信號。
下面是使用 swoole 啟動子進程,并回收子進程資源的示例代碼:
<?php use Swoole\Process; $php = "/usr/bin/env php"; $script = dirname(__DIR__) . "/task.php"; $command = "{$php} {$script}"; $process = new Process(function (Process $worker) use ($command) { $worker->exec('/bin/sh', ['-c', $command]); }); $pid = $process->start(); printf("啟動子進程 {$pid}\n"); while ($ret = Process::wait()) { $pid = intval($ret["pid"] ?? 0); printf("子進程 {$pid} 結束\n"); }
代碼解析:
$command 變量表示需要子進程腳本,通過 exec () 方法來啟動成一個子進程的方式運行,再通過 Process::wait () 訪求來等待 $command 這個子進程腳本結束,并回收進程資源。
那么,只要在收到子進程的結束信號后,再起一個相同的子進程腳本,即可實現對子進程的守護了。
于是,第一個守護子進程的程序實現代碼:
<?php use Swoole\Process; $php = "/usr/bin/env php"; $script = dirname(__DIR__) . "/task.php"; $command = "{$php} {$script}"; do { $process = new Process(function (Process $worker) use ($command) { $worker->exec('/bin/sh', ['-c', $command]); }); $pid = $process->start(); printf("啟動子進程 {$pid}\n"); } while (Process::wait());
代碼解析:
這段代碼只將啟動子進程的邏輯加到一個死循環中,好讓這個子進程腳本能夠不斷的重啟。
四、封裝成類
為了方便重用這段代碼,可以將這段代碼封裝成一個簡單的類:
<?php namespace App; use Swoole\Process; class Daemon { /** @var string */ private $command; public function __construct(string $command) { $this->command = $command; } public function run() { do { $process = new Process(function (Process $worker) { $worker->exec('/bin/sh', ['-c', $this->command]); }); $pid = $process->start(); } while (Process::wait()); } }
那么,這個 Daemon 類的使用方式如下:
<?php use App\Daemon; $php = "/usr/bin/env php"; $script = dirname(__DIR__) . "/task.php"; $command = "{$php} {$script}"; $daemon = new Daemon($command); $daemon->run();
這個簡單 Daemon 類雖然能實現對單個腳本進行重啟守護,但是,如果我們有許多個腳本同時需要守護的,這個 Daemon 類顯然是不能夠滿足需求的。
以上就是“使用swoole4實現進程的守護,自動重啟”的詳細內容,想要獲取更多swoole教程或者相關資訊歡迎關注編程學習網
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://www.wangchenghua.com/post/8200/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料
查 看2022高級編程視頻教程免費獲取