如何检查PHP-FPM是否正常运行


How to check if PHP-FPM is running properly?

php fpm网站上的文档称,php fpm是自5.3.3 起coe php的一部分

我正在运行5.3.10,如何检查它是否正常工作?我以为这是一项在端口上运行的服务?

假设您在Linux上,通过搜索进程列表来检查php-fpm是否正在运行:

ps aux | grep php-fpm

如果在IP上运行(而不是在Unix套接字上运行),那么您也可以检查端口:

netstat -an | grep :9000

或者使用nmap:

nmap localhost -p 9000

最后,我读到你可以请求状态,但根据我的经验,这被证明是不可靠的:

/etc/init.d/php5-fpm status

对于php7.0-fpm,我调用:

service php7.0-fpm status

php7.0-fpm启动/运行,进程25993

现在注意好的部分。进程名称实际上是php-fpm7.0

echo `/bin/pidof php-fpm7.0`

26334 26297 26286 26285 26282

以下是如何使用php fpm 7 上的套接字实现这一点

install socat
apt-get install socat
#!/bin/sh
  if echo /dev/null | socat UNIX:/var/run/php/php7.0-fpm.sock - ; then
    echo "$home/run/php-fpm.sock connect OK"
  else
    echo "$home/run/php-fpm.sock connect ERROR"
  fi

您还可以检查服务是否像这样运行。

service php7.0-fpm status | grep running

它将返回

活动:自周日起活动(运行)2017-04-09 12:48:09 PDT;48秒前

如果它在amilinux上帮助安装了php5.6和php-fpm的人,它是:

sudo /etc/init.d/php-fpm-5.6 status

PHP-FPM是一种在需要时生成新PHP进程的服务,通常通过nginx等快速cgi模块。您可以通过检查init.d脚本来判断(有一定的误差),例如"sudo/etc/init.d/php-fpm status"

使用的端口或unix文件套接字取决于配置,但通常只是TCP端口9000。即127.0.0.1:9000

判断它是否正确运行的最好方法是让nginx运行,并设置一个虚拟主机,将cgi快速传递到PHP-FPM,然后用wget或浏览器进行检查。

我在运行cPanel和WHM的Centos 7服务器上挣扎了一段时间,PHP-FPM有时会变得没有响应。PHP-FPM服务显示它正在运行,但不响应请求。

我的数据中心团队也在努力帮助我找到一个永久性的解决方案,但到目前为止,我们运气不佳。

在此期间,我开发了一个Node.js监控系统,该系统通过打开一个在PHP FPM上运行的测试文件来运行。系统在引用服务器的IP地址和站点主机名时同时使用HTTP://和HTTPS://调用,以防止由于网络、DNS或其他相关错误而导致的任何不必要的重新启动。如果系统没有收到有效的响应,它会重新启动PHP FPM并给我发一封电子邮件。

下面是代码和方法,如果有人觉得它有用的话。

在您的服务器上创建一个文件夹,例如/home/itilth/monitor/,并在该文件夹中创建一个名为monitor.js和init.php的文件。在可以在服务器上测试的域上创建一个testFPM.php文件。

---节点进程(monitor.js),您需要安装的唯一模块是axios(例如npm安装axios)

const axios = require('axios');
const { execSync } = require('child_process');
const failureEmail = "[your email address]";
const serverIP = "[server ip]"; //e.g. 8.8.8.8
const testDomain = "[your domain name]"; //e.g. example.com
const testFile = "testFPM.php";
const restartFPMCommand = "/scripts/restartsrv_apache_php_fpm";
const failedEmailCommand = 'mail -s '"FPM Restarted'" '+failureEmail+' < /dev/null';
function date(str,timestamp){
    var ret = "";
    if(!timestamp){
        var timestamp = Math.floor(new Date().getTime() / 1000);
        timestamp = timestamp;
    }
    else{
        timestamp = parseInt(timestamp);
    }
    var d = new Date(timestamp*1000);
    
    if(!str){var str = "Y-m-d H:i:s";}
    str = str.split("");
    var strc = str.length;
    for(var a=0;a<strc;a++){
        switch(str[a]) {
            case "d":
                var m = d.getDate()+""; if(m.length < 2){m = "0"+m;}
                ret = ret + m;
                break;
            case "j":
                var m = d.getDate()+"";
                ret = ret + m;
                break;
            case "D":
                var m = d.getDay();
                if(m == 0){m = "Sun";}
                if(m == 1){m = "Mon";}
                if(m == 2){m = "Tue";}
                if(m == 3){m = "Wed";}
                if(m == 4){m = "Thu";}
                if(m == 5){m = "Fri";}
                if(m == 6){m = "Sat";}
                
                ret = ret + m;
                break;
            case "N":
                var m = d.getDay();
                if(m == 0){m = 7;}
                ret = ret + m + "";
                break;
            case "w":
                var m = d.getDay();
                ret = ret + m + "";
                break;
            case "z":
                var start = new Date(d.getFullYear(), 0, 0);
                var diff = d - start;
                var daytime = 1000 * 60 * 60 * 24;
                var m = Math.floor(diff / daytime) - 1;
                ret = ret + m + "";
                break;
            case "S":
                var m = d.getDate();
                
                if(m == 1 || m == 21 || m == 31){m = "st";}
                if(m == 2 || m == 22){m = "nd";}
                if(m == 3 || m == 23){m = "rd";}
                if((m > 3 && m < 21) || (m > 23 && m < 31)){m = "th";}
                
                ret = ret + m;
                break;
            case "l":
                var m = d.getDay();
                if(m == 0){m = "Sunday";}
                if(m == 1){m = "Monday";}
                if(m == 2){m = "Tuesday";}
                if(m == 3){m = "Wednesday";}
                if(m == 4){m = "Thursday";}
                if(m == 5){m = "Friday";}
                if(m == 6){m = "Saturday";}
                
                ret = ret + m;
                break;
            case "W":
                var dd = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
                dd.setUTCDate(dd.getUTCDate() + 4 - (dd.getUTCDay()||7));
                var year_start = new Date(Date.UTC(dd.getUTCFullYear(),0,1));
                var week_no = Math.ceil((((dd-year_start)/86400000)+1)/7);
                var m = week_no + "";
                ret = ret + m;
                break;
            case "F":
                var m = (d.getMonth()+1);
                if(m == 1){m = "January";}
                if(m == 2){m = "February";}
                if(m == 3){m = "March";}
                if(m == 4){m = "April";}
                if(m == 5){m = "May";}
                if(m == 6){m = "June";}
                if(m == 7){m = "July";}
                if(m == 8){m = "August";}
                if(m == 9){m = "September";}
                if(m == 10){m = "October";}
                if(m == 11){m = "November";}
                if(m == 12){m = "December";}
                
                ret = ret + m;
                break;
            case "m":
                var m = (d.getMonth()+1)+""; if(m.length < 2){m = "0"+m;}
                ret = ret + m;
                break; 
            case "M":
                var m = (d.getMonth()+1);
                if(m == 1){m = "Jan";}
                if(m == 2){m = "Feb";}
                if(m == 3){m = "Mar";}
                if(m == 4){m = "Apr";}
                if(m == 5){m = "May";}
                if(m == 6){m = "Jun";}
                if(m == 7){m = "Jul";}
                if(m == 8){m = "Aug";}
                if(m == 9){m = "Sep";}
                if(m == 10){m = "Oct";}
                if(m == 11){m = "Nov";}
                if(m == 12){m = "Dec";}
                
                ret = ret + m;
                break; 
            case "n":
                var m = (d.getMonth()+1)+"";
                ret = ret + m;
                break; 
            case "t":
                var m = new Date(d.getFullYear(), d.getMonth()+1, 0);
                m = m.getDate();
                ret = ret + m + "";
                break; 
            case "L":
                var m = new Date(d.getFullYear(), 1, 0);
                m = m.getDate();
                
                if(m == 29){m = "1";}
                else{m = "0";}
                
                ret = ret + m + "";
                break;
            case "o":
                ret = ret + d.getFullYear()+"";
                break;
            case "Y":
                ret = ret + d.getFullYear()+"";
                break;
            case "y":
                var m = d.getFullYear()+"";
                m = m.substr((m.length-2),2);
                
                ret = ret + m + "";
                break;
            case "a":
                var m = d.getHours();
                if(m < 12){m = "am"}
                else{m = "pm"}; 
                
                ret = ret + m + "";
                break;
            case "A":
                var m = d.getHours();
                if(m < 12){m = "AM"} 
                else{m = "PM"}; 
                ret = ret + m + "";
                break;
            case "B":
                var m = Math.floor((((d.getUTCHours() + 1) % 24) + d.getUTCMinutes() / 60 + d.getUTCSeconds() / 3600) * 1000 / 24);
                ret = ret + m + "";
                break;
            case "g":
                var m = d.getHours();
                
                if(m > 12){m = m - 12;}
                
                ret = ret + m + "";
                break;
            case "G":
                var m = d.getHours();
                
                ret = ret + m + "";
                break;
            case "h":
                var m = d.getHours();
                if(m > 12){m = m - 12;}
                
                m = m + ""; if(m.length < 2){m = "0"+m;}
                
                ret = ret + m + "";
                break;
            case "H":
                var m = d.getHours();
                
                m = m + ""; if(m.length < 2){m = "0"+m;}
                
                ret = ret + m + "";
                break;
            case "i":
                var m = d.getMinutes();
                
                m = m + ""; if(m.length < 2){m = "0"+m;}
                
                ret = ret + m + "";
                break;
            case "s":
                var m = d.getSeconds();
                
                m = m + ""; if(m.length < 2){m = "0"+m;}
                
                ret = ret + m + "";
                break;
            default:
                ret = ret + str[a] + "";
        }
    }
    
    return ret;
}
function log(message){
    console.log(date("Y-m-d H:i:s") + " - "+message)
}
var checking = false;
async function checkStatus(host,type){
    const startTime = Date.now();
    var r = "";
    try {
        const res = await axios.get(type+serverIP+'/'+testFile, {
            timeout: 4000,
            headers: {
                'Host': host,
                // other headers
            }
        })
        const endTime = Date.now();
        const elapsedTime = endTime - startTime;
        if (res.status >= 200 && res.status < 306) {
            if(res.data == "fpm-fcgi"){
                r = 'UP in '+elapsedTime+" => "+res.data;
            }
            else{
                r = 'DOWN ' + res.status + " in "+elapsedTime+" => "+res.data;
            }
        } else {
            r = 'DOWN ' + res.status + " in "+elapsedTime;
        }
    } catch (err) {
        r = 'DOWN ' + err.message;
    }
    
    return r;
}
async function checkAStatus(){
    if(!checking){
        checking = true;
        var httpStatus = await checkStatus(testDomain,"http://");
        var httpsStatus = await checkStatus(testDomain,"https://");
        if(httpStatus.substring(0,4) == "DOWN" || httpsStatus.substring(0,4) == "DOWN"){
            log("Restarting FPM...");
            try {
                const output = execSync(restartFPMCommand);
                console.log(output.toString());
            } catch (error) {
                console.error(`execSync error: ${error}`);
            }
            try {
                execSync(failedEmailCommand);
            } catch (error) {
                console.error(`execSync error: ${error}`);
            }
        }
        
        log("HTTP: "+httpStatus+" | HTTPS: "+httpsStatus);
        checking = false;
    }
    else{
        log("Already checking.");
    }
}
  
// Check the website status every 10 seconds
setInterval(checkAStatus, 10000);

--PHP测试文件(testFPM.PHP)

<?php
$sapiType = php_sapi_name();
echo $sapiType;
?>

--PHP INIT脚本(INIT.PHP),可用于通过cron启动/停止/重新启动和检查监视器进程。此脚本还将监视器日志输出到同一文件夹中的log.log中,可以按如下方式使用。

php/home/itilth/monitor/init.php检查

php/home/itilt/monitor/init.php停止

php/home/itilth/monitor/init.php启动

php/home/itilth/monitor/init.php重新启动

查看日志文件:tail-f/home/itilth/monitor/log.log

#!/usr/bin/php -q
<?
$command = $argv[1];
global $node_process;
global $pid_file;
global $log_file;
global $log_levels;
global $first_log;
$log_levels = array();
$log_levels["error"] = true;
$log_levels["info"] = false;
$log_levels["general"] = true;
$node_process = "node ".__DIR__."/monitor.js";
$pid_file = __DIR__."/pid";
$log_file = __DIR__."/log";
$first_log = true;
function write_log($data,$type="info",$add=false,$nodate=false){
    global $log_file;
    global $log_levels;
    global $first_log;
    
    if($log_levels[$type]){
        $date_string = "";
        $color = "'x1b[2m";
        if($type == "general"){$color = "'x1b[36m";}
        if($type == "error"){$color = "'x1b[31m";}
        
        if(!$nodate){
            $date = "INIT - ".date("D M d Y H:i:s 'G'M'TO (T) ");
        }
        else{
            $date = "";
        }
        $string = "";
        if(!$add && !$first_log){$string .= "'n";}
        $string .= $color;
        if(!$add){$string .= $date;}
        $string .= $data;
        $string .= "'x1b[0m";
        
        if($add){
            $string .= "'n";
        }
        
        file_put_contents($log_file.".log",$string,FILE_APPEND);
        
        $first_log = false;
    }
}
function pid(){
    return "test";
}
function is_running(){
    global $node_process;
    write_log("Checking if process is running.");
    
    $pid = pid();
    
    if($pid != ""){
        exec("ps aux | grep node",$output,$result);
        $outputc = count($output);
        $found = false;
        for($a=0;$a<$outputc;$a++){
            write_log($output[$a]);
            if(strpos($output[$a],$node_process) !== false){
                $found = true;
            }
        }
        
        if($found){
            return true;
        }
        else{
            return false;
        }
    }
    else{
        return false;
    }
}
function start(){
    global $node_process;
    global $client_user;
    if(!is_running()){
        write_log("Starting Node Process:");
        exec("nohup ".$node_process." >> ".__DIR__."/log".".log 2>&1 &");
        write_log("-----------------------------------------------------------------------------------","general",false,true);
        write_log("Starting Node Server... ","general");
        
        sleep(1);
        
        if(is_running()){
            write_log("[OK]","general",true);
        }
        else{
            write_log("[FAILED]","error",true);
        }
    }
    else{
        write_log("Process already running");
    }
}
function stop(){
    global $node_process;
    
    if(!is_running()){
        write_log("Process not running.");
    }
    else{
        write_log("Stopping process...","general");
        $pid = "";
        $nout = array();
        $output = array();
        $result = array();
        exec("ps aux | grep '".$node_process."'",$output,$result);
        $outputc = count($output);
        $found = false;
        for($a=0;$a<$outputc;$a++){
            if(strpos($output[$a],$node_process) !== false && strpos($output[$a],"grep") === false){
                /*write_log($output[$a],"general",true);*/
                $found = true;
                $out = explode(" ",$output[$a]);
                $outc = count($out);
                for($a=0;$a<$outc;$a++){
                    if(trim($out[$a]) != ""){
                        $nout[] = $out[$a];
                    }
                }
            }
        }
        if($found){
            $pid = $nout[1];
            write_log("Killing process ".$pid."... ","general");
            
            exec("kill ".$pid);
            
            if(!is_running()){
                write_log("[OK]","general",true);
            }
            else{
                write_log("[FAILED]","error",true);
            }
        }
        else{
            write_log("[PROCESS NOT FOUND][FAILED]","error",true);
        }
    }
}
function restart(){
    stop();
    start();
}
function check(){
    write_log("Checking if running... ","general");
    if(is_running()){
        write_log("Process is running [OK]","general",true);
    }
    else{
        write_log("Process is not running [FAILED]","error",true);
        restart(); 
    }
}
if($command == ""){$command = "check";}
write_log("Command: ".$command);
if($command == "start"){
    start();
}
if($command == "stop"){
    stop();
}
if($command == "restart"){
    restart();
}
if($command == "check"){
    check();
}
?>

用于自动重启php-fpm:的bash脚本

#!/bin/bash
is_running=`service php7.4-fpm status | grep running`
if [[ ! $is_running ]]
then
    echo 'php7.4-fpm is running'
else
    echo 'php7.4-fpm is not running';
fi

每5分钟检查一次的Cron配置(/root/check_php7.4_status.sh-bash脚本的路径):

*/5 * * * * /root/check_php7.4_status.sh 2>&1 >> '/root/check_php7.4_status.log'

这是我写的一个琐碎但我认为很漂亮的脚本,它可以从CRON运行,并将检查服务器上安装的php-fpm的所有版本是否都在运行。这是为Ubuntu 22.04写的,所以YMMV。(这些信息部分是从这个页面上的信息中收集的,但奇怪的是,没有人采取额外的步骤来使用运行"php-fpm status"时返回的状态

其想法是对/etc/init.d中找到的每个php-fpm版本进行状态检查,然后检查返回代码。如果返回代码不为null,则表示出现了问题,我们会发出通知并尝试重新启动。

#!/bin/bash
NOTIFY=me@my.address
for each in /etc/init.d/php*fpm
do
    $each status  > /dev/null
    if [ $? -ne 0 ]
    then
        logger "$each was not running on $( hostname ) "
        mail -s "$each was not running on $( hostname ) " $NOTIFY < /dev/null
        $each restart
    fi
done