首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP CLI 實現守護進程的兩種方案詳解

     編輯:PHP 相關知識

PHP CLI 實現守護進程的兩種方案詳解

長期運行的後台服務(如消息隊列消費者、WebSocket 服務、定時任務)需以守護進程形式運行。PHP 本身無內置 daemon() 函數,但可通過系統工具或 PCNTL 擴展實現。

方案一:使用 nohup + &(簡單快速)

# 後台運行,輸出重定向到日誌
nohup php worker.php >> storage/logs/worker.log 2>&1 &

# 查看進程
ps aux | grep worker.php

# 停止進程
kill -TERM 

優缺點

優點缺點
無需修改代碼,零侵入無法在代碼中控制守護化邏輯
適合臨時/簡單腳本標準輸入/輸出/錯誤需手動重定向
系統級進程管理進程管理依賴外部工具(systemd/supervisor)

方案二:PHP 代碼內部雙 Fork 實現(標準 Unix 守護進程模式)

<?php
/**
 * 將當前進程轉為守護進程
 * 需啟用 pcntl、posix 擴展
 */
function daemonize(): void {
    // 第一次 fork:父進程退出,子進程成為新會話組長
    $pid = pcntl_fork();
    if ($pid === -1) {
        die("fork #1 failed\n");
    } elseif ($pid > 0) {
        exit(0); // 父進程退出
    }

    // 脫離控制終端,創建新會話
    if (posix_setsid() === -1) {
        die("setsid failed\n");
    }

    // 第二次 fork:防止重新獲得控制終端
    $pid = pcntl_fork();
    if ($pid === -1) {
        die("fork #2 failed\n");
    } elseif ($pid > 0) {
        exit(0); // 第一子進程退出,第二子進程成為最終守護進程
    }

    // 可選:切換工作目錄到根目錄,避免掛載點卸載問題
    chdir('/');

    // 可選:重設文件創建掩碼
    umask(0);

    // 可選:關閉標準流並重定向(生產環境建議)
    fclose(STDIN);
    fclose(STDOUT);
    fclose(STDERR);
    $null = fopen('/dev/null', 'r');
    fopen('/dev/null', 'w');
    fopen('/dev/null', 'w');
}

// 業務邏輯入口
daemonize();

// 模擬長期任務
while (true) {
    // 處理業務...
    sleep(10);
}

雙 Fork 原理圖解

用戶終端啟動
      │
      ▼
┌─────────────┐
│  父進程      │── fork() ──▶ 父進程 exit(0) 返回終端
└─────────────┘
      │
      ▼ 子進程(會話組長)
┌─────────────┐
│  子進程1     │── setsid() 脫離終端
└─────────────┘
      │
      ▼
┌─────────────┐
│  子進程1     │── fork() ──▶ 子進程1 exit(0)
└─────────────┘
      │
      ▼ 子進程2(非會話組長,無法重獲終端)
┌─────────────┐
│  守護進程    │◀── 最終運行實體
└─────────────┘

生產環境建議:使用 Supervisor 管理

雖然 PHP 可自守護,但生產環境強烈建議使用 Supervisor 等進程管理器:

; /etc/supervisor/conf.d/worker.conf
[program:php-worker]
command=php /var/www/app/worker.php
autostart=true
autorestart=true
user=www-data
numprocs=4
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/var/log/supervisor/worker.log
redirect_stderr=true

Supervisor 優勢

  • 自動重啟崩潰進程
  • 多進程管理、日誌輪轉、啟停控制
  • Web 管理界面、API 集成
  • 系統啟動自動拉起

總結選型

場景推薦方案
臨時測試、簡單腳本nohup + &
需在代碼中控制守護化PHP 雙 Fork
生產環境長期服務Supervisor + 普通 CLI 腳本

理解守護進程原理,選擇合適的部署方式,是 PHP 後台服務穩定運行的基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved