fastcgi throws 502 gateway errors on nginx after a few days
One thing that I noticed is that running free shows a little swap space used when this crops up. After restarting fastcgi, the swap frees up.
For fastcgi, I'm using the standard tutorial recommendation – it's php-cgi running in external fastcgi mode.
This is my config file:
#
# Settings for php-cgi in external FASTCGI Mode
#
# Should php-fastcgi run automatically on startup? (default: no)
START=yes
# Which user runs PHP? (default: www-data)
EXEC_AS_USER=
# Host and TCP port for FASTCGI-Listener (default: localhost:9000)
FCGI_HOST=localhost
FCGI_PORT=9000
# Environment variables, which are processed by PHP
PHP_FCGI_CHILDREN=5
PHP_FCGI_MAX_REQUESTS=1000
So, here's what I'm wondering: What could this be? What should I modify to try to fix this? Why is fastcgi dying on me?
I'm pretty good about figuring things out on my own, but I haven't been able to get anywhere through Google searches and I'm just not sure where to start. Thanks in advance for any tips you can throw my way!
13 Replies
It sort of sounds like the problem could be that 4 worker_processes with 1024 connections each is just too much for 5 fcgi children.
When I was on Ubuntu 8.04 LTS with PHP 5.2.4, it has heaps of problems and sometimes fastcgi would die multiple times a day depending on the load. Changed to Debian 5 with PHP 5.2.6 and it's now fine. 70k-100k page views per day (all executed through PHP) and 5 FCGI children is enough.
That will not be a fun day.
I think I'm might try spawn-fcgi first though.
Things right now are working fine with more children. But, again, sorta too early to really call it.
Anyway, if your fastcgi process keeps committing suicide, put the startup script in another shell script, inside an infinite loop. That way, whenever the process exits, a new one will be started right away.
@hybinet:
Debian 5 is newer than Ubuntu Hardy…
Exactly
> Anyway, if your fastcgi process keeps committing suicide, put the startup script in another shell script, inside an infinite loop. That way, whenever the process exits, a new one will be started right away.
It won't work because the process does not die – they just become zombies and require a kill -9
What I did before was running another script scanning /var/log/nginx/error.log -- something like a tail -f but immediately restart php-fcgi if some 502 error has been detected (and send me an email for notification). Again, upgrading to a different PHP version completely solves it.
@scotty:
@hybinet:Debian 5 is newer than Ubuntu Hardy…
Exactly
:)
What happened there? I read "Debian" and thought "Ubuntu".
Because I am an idiot. Just like I put this thread in the LAMP forum and requested help with nginx.
> It won't work because the process does not die – they just become zombies and require a kill -9
Yes, this is the issue. It just happened again today. With 15 children running, I haven't noticed any issues with the pages that are being served, but the swap thing has cropped up again with fastcgi.
I hadn't checked the error log for nginx, mine is in /usr/local/nginx/logs:
2009/03/30 18:21:31 [alert] 16982#0: worker process 16986 exited on signal 9
2009/04/04 14:48:35 [alert] 11041#0: worker process 11044 exited on signal 9
2009/04/06 03:51:22 [alert] 7300#0: worker process 7304 exited on signal 9
2009/04/06 04:01:51 [alert] 8350#0: worker process 8354 exited on signal 9
2009/05/08 15:47:27 [alert] 2464#0: worker process 2466 exited on signal 9
So, I guess the fastcgi children go zombie one at a time until it impacts nginx and then boom!
Maybe I'll try spawn-cgi when I have a chance. Easier than switching out to Debian.
> What I did before was running another script scanning /var/log/nginx/error.log – something like a tail -f but immediately restart php-fcgi if some 502 error has been detected (and send me an email for notification). Again, upgrading to a different PHP version completely solves it.
Thanks for the tip. I assume you set it up in your hourly cron? I'll see if I can't figure out how to write up something like that for now.
I also thought I could just run a daily cron that restarts fastcgi.
> Thanks for the tip. I assume you set it up in your hourly cron? I'll see if I can't figure out how to write up something like that for now.
Well. Not exactly. Having it running hourly would mean that I am loosing one hour of traffic which is not desirable.
Anyway. Here's the script:
What it does is basically
1. Scans /var/log/nginx/error.log every 2 seconds (do filesize first so should have minimum impact on IO)
2. If 104: Connection reset by peer or 111: Connection refused are detected, start respawning the PHP process
When it tries to respawn, it
1. /etc/init.d/spawn-fcgi-php stop
2. Wait 2 seconds
3. killall -9 php-cgi
4. /etc/init.d/spawn-fcgi-php start
5. Send an email to tell me that something is wrong.
It should cut the downtime to minimum. You can just run it (as root) and it will daemonize to scan the Nginx error log file. Anyway, it has been customised to suit my environment but feel free to use it (at your own risk
My latest attempt? I lowered PHPFCGIMAX_REQUESTS to 500. Hopefully, fcgi spawns will recycle before they zombie now. I had this previously set at 1000.
Apache+PHP is widely understood and the apache parent seems to do a decent job of keeping the child processes in line. Proxy to apache with nginx and you get the best of both worlds. Nginx can handle static files and keep alives with very low overhead and lets apache get back to work on the next dynamic page while nginx handles returning the script result to the client.