2014-12-05 164 views
4

如何在不將簡單的cli運行時改爲php-fpm的情況下從web管理守護進程?管理php守護進程

在OS啓動後,守護進程會自動啓動,並在不使用php-fpm池的情況下作爲cli應用程序工作。所以守護進程生態系統的基本思想是不用php-fpm pool(CLI-SAPI)。

服務器配置:

  1. 的Debian 7
  2. 阿帕奇2.2
  3. 的php5-FPM(V 35年4月5日) - 的mod_fastcgi
  4. daemon.php
  5. daemon_manager.php - 管理腳本從命令行啓動|停止|重新啓動|終止daemon.php。
  6. daemon_manager_web.php - 用於管理來自瀏覽器的守護程序的管理員腳本。

daemon.php是一個普通的PHP後臺程序是這樣的:

<?php 
    declare(ticks=1); 
    ini_set("max_execution_time", "0"); 
    ini_set("max_input_time",  "0"); 
    set_time_limit(0); 
    /* Catching signals */ 
    function sig_handler($signo) { 
     switch ($signo) { 
      case SIGQUIT: 
      case SIGTERM: 
       // some work 
     pcntl_wait($status); 
       break; 
      //... 
     } 
    } 

    pcntl_signal(SIGTERM, 'signal_handler'); 
    pcntl_signal(SIGQUIT, 'signal_handler'); 

    $newpid = pcntl_fork(); 
    if ($newpid == -1) { 
     throw new Exception('Cannot fork porcess'); 
    } elseif ($newpid) { 
     print "Starting daemon under pid=$newpid\n"; 
     // ... 
     exit; 
    } 

的問題。

由於PCNTL函數不能從Web獲得,我通過exec(),shell_exec()等函數管理守護進程。但是當我停止並從瀏覽器中使用daemon_manager_web.php再次啓動守護進程時,它通常會啓動,但是可以在php-fpm池下運行。

進程重新啓動之前列表:

$ ps aux | grep php 
root  5952 0.0 2.9 69008 14952 pts/0 S 14:24 0:00 php /var/www/daemon.php 

$ service php5-fpm status 
php5-fpm.service - LSB: starts php5-fpm 
     Loaded: loaded (/etc/init.d/php5-fpm) 
     Active: active (running) since Fri, 05 Dec 2014 11:28:25 +0200; 11h ago 
    Process: 1003 ExecStart=/etc/init.d/php5-fpm start (code=exited, status=0/SUCCESS) 
     CGroup: name=systemd:/system/php5-fpm.service 
       ├ 1627 php-fpm: master process (/etc/php5/fpm/php-fpm.conf) 
       ├ 9562 php-fpm: pool www 
       ├ 9605 php-fpm: pool www 
       └ 9633 php-fpm: pool www 

重啓後的進程列表中的瀏覽器:

$ service php5-fpm status 
php5-fpm.service - LSB: starts php5-fpm 
     Loaded: loaded (/etc/init.d/php5-fpm) 
     Active: active (running) since Fri, 05 Dec 2014 11:28:25 +0200; 11h ago 
    Process: 1003 ExecStart=/etc/init.d/php5-fpm start (code=exited, status=0/SUCCESS) 
     CGroup: name=systemd:/system/php5-fpm.service 
       ├ 1627 php-fpm: master process (/etc/php5/fpm/php-fpm.conf) 
       ├ 4987 php-fpm: pool www 
       ├ 5040 php-fpm: pool www 
       ├ 9432 php-fpm: pool www 
       └ 9492 /usr/bin/php /var/www/daemon.php 
+0

您正在使用HTTP啓動守護進程嗎?這沒有任何意義,通過CLI啓動腳本,如果必須通過套接字和信號「交談」。 – 2014-12-06 02:41:07

+0

如果我想使用套接字管理守護進程,那麼我必須創建套接字服務器並打開一些端口來與它進行通信。我認爲這不安全。該解決方案還添加了另一個抽象的「談話」層,並且不適合。 – Slam 2014-12-06 12:36:29

回答

2

你應該以任何方式開始通過Apache守護進程。這樣做的正確方法是啓動一個守護進程(由supervisord管理,我在生產環境中擁有相當不錯的記錄)和opening a file socket(AF_UNIX),您在其上執行了socket_select()以及空閒等待一些觸發處理的輸入。這樣,「接口」(在Apache上)就連接到套接字並寫入它。

關於該主題,我發現在PHP中編寫守護程序非常繁瑣,您可能希望選擇一個庫來處理您的基本問題(無法推薦任何內容)或甚至更適合該事件的其他工具典型的守護進程循環(node.js?)

+0

所以我應該打開文件套接字並在守護進程中使用socket_select()?或者我需要創建一個守護進程管理器(例如supervisord)?你能告訴我更多關於溝通過程嗎? – Slam 2014-12-07 22:16:04

+0

@Slam是的,你可以在守護進程中打開套接字並在其中執行'while(true)',用'socket_select()'檢查套接字。你的客戶端代碼(在Apache中運行)將'fsockopen()'該套接字並寫入它。 – 2014-12-12 16:13:16

+0

非常感謝,這是一個好主意。 – Slam 2014-12-29 22:40:40