Marty Wallace
Marty Wallace

Reputation: 35754

How to check if PHP-FPM is running properly?

The documentation on php fpm website says that php fpm is part for coe php as of 5.3.3

I am running 5.3.10, how can i check that it is working correctly? I thought it was a service that ran on a port?

Upvotes: 72

Views: 255718

Answers (11)

aeu
aeu

Reputation: 151

Like one of the other answers on this thread I ran into this issue also, on Centos as well as on Rocky Linux.

The reason this is happening is that php-fpm maxes out pools, but keeps running. You think its alive, but it isnt. If you do a systemctl status php-fpm you get something back that looks like this:

# systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
 Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; preset: disabled)
 Active: active (running) since Wed 2025-02-12 16:57:25 UTC; 2 days ago
 Main PID: 378180 (php-fpm)
 Status: "Processes active: 50, idle: 0, Requests: 5931, slow: 0, Traffic: 0.00req/sec"
  Tasks: 51 (limit: 10890)
 Memory: 266.1M
    CPU: 3min 22.585s
 CGroup: /system.slice/php-fpm.service
         ├─378180 "php-fpm: master process (/etc/php-fpm.conf)"
         ├─378181 "php-fpm: pool www"
         ├─378182 "php-fpm: pool www"
         ├─378183 "php-fpm: pool www"
         ├─378184 "php-fpm: pool www"
         ├─378185 "php-fpm: pool www"
         ├─378187 "php-fpm: pool www"
         ├─378224 "php-fpm: pool www"
         ├─379205 "php-fpm: pool www"
         ├─379207 "php-fpm: pool www"
         ├─382316 "php-fpm: pool www"
         ├─385428 "php-fpm: pool www"
         ├─385430 "php-fpm: pool www"
         ├─385431 "php-fpm: pool www"
         ├─385432 "php-fpm: pool www"
         ├─385436 "php-fpm: pool www"
         ├─409352 "php-fpm: pool www"
         ├─409360 "php-fpm: pool www"
         ├─409361 "php-fpm: pool www"
         ├─409366 "php-fpm: pool www"
         ├─409367 "php-fpm: pool www"
         ├─409368 "php-fpm: pool www"
         ├─409369 "php-fpm: pool www"
         ├─409375 "php-fpm: pool www"
         ├─409376 "php-fpm: pool www"
         ├─409377 "php-fpm: pool www"
         ├─409378 "php-fpm: pool www"
         ├─409379 "php-fpm: pool www"
         ├─426730 "php-fpm: pool www"
         ├─426731 "php-fpm: pool www"
         ├─426732 "php-fpm: pool www"
         ├─451531 "php-fpm: pool www"
         ├─451533 "php-fpm: pool www"
         ├─468298 "php-fpm: pool www"
         ├─468313 "php-fpm: pool www"
         ├─468314 "php-fpm: pool www"
         ├─468315 "php-fpm: pool www"
         ├─468316 "php-fpm: pool www"
         ├─468317 "php-fpm: pool www"
         ├─468318 "php-fpm: pool www"
         ├─468319 "php-fpm: pool www"
         ├─468320 "php-fpm: pool www"

This looks like it's running but it isn't, because php-fpm won't return any requests.

This script counts the pools and restarts if it's over 40. I have this in a cron.

#!/usr/bin/bash
#
# resarts PHP FPM if it dies
#
pool_count=$(systemctl status php-fpm | grep -o "pool" | wc -l)

if [ "$pool_count" -gt 40 ]; then
    systemctl restart php-fpm >> /var/log/aeu.log
    echo "`date` - php-fpm not running.  Restart required" >> /var/log/aeu.log;
fi

I can't imagine I'll need to update this because it's so trivial, but here's a github link ayway.

Enjoy!

https://github.com/aeu/misc/tree/master/php-fpm

Upvotes: 0

Rainer Glüge
Rainer Glüge

Reputation: 1901

On Linux with systemd use

systemctl status php8.3-fpm,

with the correct version number.

Upvotes: 1

AlexeyP0708
AlexeyP0708

Reputation: 432

To check the connection

Debian apt-get install libfcgi0ldbl

Alpine apk add fcgi

and run command cgi-fcgi -bind -connect ${host}:${PORT} || echo 'Error'

This is useful for checking the health of a docker container.

HEALTHCHECK CMD "cgi-fcgi -bind -connect localhost:9000 >/dev/null 2>&1 || exit 1"

to run a specific script

SCRIPT_FILENAME=/mnt/data/php/www/phpinfo/test.php \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect ${host}:${PORT} || \
echo 'Error'

Upvotes: 3

davidgo
davidgo

Reputation: 279

Here is a trivial - but I think nifty - script I wrote which can be run from CRON and will check that all versions of php-fpm installed on the server are running. This was written for Ubuntu 22.04, so YMMV. (This information is partially gleaned from information on this page, but strangely none took the extra step of using the status returned when you run "php-fpm status"

The idea is to do a status check on each version of php-fpm found in /etc/init.d , and then check the return code. If the return code is not null, something is wrong and we do notifications and attempt a restart.

#!/bin/bash

[email protected]

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

Upvotes: 0

Kobus Etsebeth
Kobus Etsebeth

Reputation: 11

I've been struggling for a while on a Centos 7 server running cPanel and WHM with PHP-FPM becoming unresponsive at times. The PHP-FPM service shows it is running, but does not respond to requests.

The team at my datacenter is also trying to assist me with finding a permanent solution, but thus far we haven't had any luck.

In the interim, I have developed a Node.js monitoring system that operates by opening a test file that runs on PHP FPM. The system utilizes both HTTP:// and HTTPS:// calls while referencing the server's IP address and site hostname to prevent any unwarranted restarts resulting from network, DNS, or other related errors. In the event that the system does not receive a valid response, it restarts PHP FPM and sends me an email.

The code and method is below if anyone may find it useful.

Create a folder on your server e.g. /home/itdint/monitor/ and create a file called monitor.js and init.php in that folder. Create a testFPM.php file on a domain you can test on the server.

---Node Process (monitor.js), the only module you should need to install is axios (e.g. npm install 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 Test File (testFPM.php)

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

--PHP INIT script (init.php) that can be used to start/stop/restart and check the monitor process via cron. This script also outputs the monitor logs to log.log in the same folder and can be used as follows.

php /home/itdint/monitor/init.php check

php /home/itdint/monitor/init.php stop

php /home/itdint/monitor/init.php start

php /home/itdint/monitor/init.php restart

view log file: tail -f /home/itdint/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();
}
?>

Upvotes: 1

The bash script for the auto restart php-fpm:

#!/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

Cron configuration for the checking every 5 minutes(/root/check_php7.4_status.sh - path to the bash script):

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

Upvotes: 1

prosti
prosti

Reputation: 46401

For php7.0-fpm I call:

service php7.0-fpm status

php7.0-fpm start/running, process 25993

Now watch for the good part. The process name is actually php-fpm7.0

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

26334 26297 26286 26285 26282

Upvotes: 40

Jason
Jason

Reputation: 1678

Here is how you can do it with a socket on 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

You can also check if the service is running like this.

service php7.0-fpm status | grep running

It will return

Active: active (running) since Sun 2017-04-09 12:48:09 PDT; 48s ago

Upvotes: 14

bitkahuna
bitkahuna

Reputation: 61

in case it helps someone, on amilinux, with php5.6 and php-fpm installed, it's:

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

Upvotes: 6

SamGoody
SamGoody

Reputation: 14488

Assuming you are on Linux, check if php-fpm is running by searching through the process list:

ps aux | grep php-fpm

If running over IP (as opposed to over Unix socket) then you can also check for the port:

netstat -an | grep :9000

Or using nmap:

nmap localhost -p 9000

Lastly, I've read that you can request the status, but in my experience this has proven unreliable:

/etc/init.d/php5-fpm status

Upvotes: 85

Jared Kipe
Jared Kipe

Reputation: 1187

PHP-FPM is a service that spawns new PHP processes when needed, usually through a fast-cgi module like nginx. You can tell (with a margin of error) by just checking the init.d script e.g. "sudo /etc/init.d/php-fpm status"

What port or unix file socket is being used is up to the configuration, but often is just TCP port 9000. i.e. 127.0.0.1:9000

The best way to tell if it is running correctly is to have nginx running, and setup a virtual host that will fast-cgi pass to PHP-FPM, and just check it with wget or a browser.

Upvotes: 0

Related Questions