在 CLI 模式下,透過 PID 檔案與 ps 指令實現 PHP 守護另一個 PHP 進程的監控機制。適用於長期運行的背景任務、佇列消費者、WebSocket 服務等場景。
ps -p PID 驗證進程存活<?php
$id = intval($argv[1] ?? 0);
if (empty($id)) exit;
$pidFile = "pid{$id}.pid";
// 寫入當前 PID
file_put_contents($pidFile, getmypid());
// 模擬長期運行任務(實際替換為你的業務邏輯)
while (true) {
// 更新心跳時間戳(可選)
file_put_contents($pidFile, getmypid() . "\n" . time());
// 你的業務邏輯:處理佇列、WebSocket 循環等
sleep(100); // 示例:休眠 100 秒
}
?>
<?php
$id = intval($argv[1] ?? 0);
$pidFile = "pid{$id}.pid";
if (!file_exists($pidFile)) {
echo "not run\n";
exit;
}
$content = file_get_contents($pidFile);
if (empty(trim($content))) {
echo "not run\n";
exit;
}
// 取得第一行 PID
$pid = trim(explode("\n", $content)[0]);
// 使用 ps 指令精確檢查進程(避免同名檔案誤判)
exec("ps p {$pid} | grep b.php", $output);
if (count($output) > 0) {
echo "running\n";
} else {
echo "not run\n";
// 可選:自動重啟邏輯
// exec("php b.php {$id} > /dev/null 2>&1 &");
}
?>
pcntl_signal 優雅關閉,清理 PID 檔案pcntl_fork 或 Symfony Process 元件管理子進程# /etc/systemd/system/php-worker@.service [Unit] Description=PHP Worker %i After=network.target [Service] Type=simple User=www-data WorkingDirectory=/var/www/app ExecStart=/usr/bin/php b.php %i Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
啟用:systemctl enable --now php-worker@1