Having PHP-FPM crash often seems quite inevitable when there’s a long debugging list of third-party modules, memory leaks, server configurations, resources and the list goes on. There’s just too much to look into.
Disclaimer: As I’m frequently updating the original guides and installers here on TeaNazaR.com, I will not be responsible for any brick issues if you were to follow my obsolete guides copied elsewhere. Thus subscribe to this post to get latest updates. Modifying any part of a device may void its warranty.
Trying to upgrade and tweak PHP-FPM, MySQL and Nginx setup to match my NAS limited memory constrain (256MB) don’t seem to help much. PHP-FPM would just crash while doing some rather heavy jobs such as image processing. And sometimes it would just gave up out of no where even there’s still enough RAM to handle the request. You could just imagine waking up and your site is totally offline. This is a nightmare for most small site owners. They could be missing potential hits. Those sites with thousands hits would probably have gigabytes of RAM equipped, so lesser prone to this problem.
After hours of googling for solutions with no definite answer, I though of an approach to probe the PHP-FPM process in case it goes down. This check was done every fifteen minutes via root account cronjob calling a shell script. The shell script on the other hand triggers a Curl request to my site’s WordPress PHP cron script. If the result is not HTTP “200 OK”, I would expect the PHP-FPM process is no longer active, after which the shell script will try to restart the PHP-FPM service. This script will also check Nginx and MySQL services just in case they too needed an emergency jumpstart.
CheckPHP-FPM.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/bin/sh # CheckPHP-FPM.sh v1.0 by Nazar78 @ TeaNazaR.com ################################################ # Simple script to monitor if PHP-FPM is still alive. # It will try to restart PHP-FPM/Nginx/MySQL accordingly and sendmail failures. # PS: Feel free to distribute but kindly retain the credits (-: ################################################ NICE="0" DOMAIN="TeaNazaR.com" REQUEST="wp-cron.php?doing_wp_cron" FROM="webmaster@teanazar.com" TO="webmaster@teanazar.com" RESULT="$(curl -sL --head $DOMAIN/$REQUEST|grep "HTTP/1.")" if ! [[ "$RESULT" =~ "200 OK" ]];then PHP="successfully..." nice -n$NICE $(ls /etc/init.d/php*fpm) restart||PHP="FAILED!" NGINX="Nginx is ok." ps -ef|grep nginx|grep -v grep||NGINX="ERROR" if [ "$NGINX" = "ERROR" ];then NGINX="Nginx restaring successfully..." nice -n$NICE /etc/init.d/nginx restart||NGINX="Nginx restaring FAILED!" fi MYSQL="MySQL is ok." ps -ef|grep mysqld|grep -v grep||MYSQL="ERROR" if [ "$MYSQL" = "ERROR" ];then MYSQL="MySQL restaring successfully..." nice -n$NICE $(ls /etc/init.d/mysql*) restart||MYSQL="MySQL restaring FAILED!" fi echo -e "To:$TO\nFrom:$FROM\nSubject:$DOMAIN Error\n\n$RESULT\n\nPHP5-FPM restarting $PHP\n$NGINX\n$MYSQL\n"|sendmail "$TO" fi |
This works as intended but I wasn’t satisfied because there’s a fifteen minutes gap in between the checks which visitors will still get 502 errors when PHP-FPM goes offline. Another better workaround, “Dealing PHP-FPM Crash & Nginx 502 Bad Gateway Error with Perl FastCGI“…