sazary
sazary

Reputation: 966

Gunicorn sync workers spawning processes

We're using Django + Gunicorn + Nginx in our server. The problem is that after a while we see lot's of gunicorn worker processes that have became orphan, and a lot other ones that have became zombie. Also we can see that some of Gunicorn worker processes spawn some other Gunicorn workers. Our best guess is that these workers become orphans after their parent workers have died.
Why Gunicorn workers spawn child workers? Why do they die?! And how can we prevent this?
I should also mention that we've set Gunicorn log level to debug and still we don't see any thing significant, other than periodical log of workers number, which reports count of workers we wanted from it.

UPDATE This is the line we used to run gunicorn:

gunicorn --env DJANGO_SETTINGS_MODULE=proj.settings proj.wsgi --name proj --workers 10 --user proj --group proj --bind 127.0.0.1:7003 --log-level=debug --pid gunicorn.pid --timeout 600 --access-logfile /home/proj/access.log --error-logfile /home/proj/error.log

Upvotes: 20

Views: 5906

Answers (3)

firelynx
firelynx

Reputation: 32194

This sounds like a timeout issue.

You have multiple timeouts going on and they all need to be in a descending order. It seems they may not be.

For example:

  • Nginx has a default timeout of 60 seconds
  • Gunicorn has a default timeout of 30 seconds
  • Django has a default timeout of 300 seconds
  • Postgres default timeout is complicated but let's pose 60 seconds for this example.

In this example, when 30 seconds has passed and Django is still waiting for Postgres to respond. Gunicorn tells Django to stop, which in turn should tell Postgres to stop. Gunicorn will wait a certain amount of time for this to happen before it kills django, leaving the postgres process as an orphan query. The user will re-initiate their query and this time the query will take longer because the old one is still running.

I see that you have set your Gunicorn tiemeout to 300 seconds.

This would probably mean that Nginx tells Gunicorn to stop after 60 seconds, Gunicorn may wait for Django who waits for Postgres or any other underlying processes, and when Nginx gets tired of waiting, it kills Gunicorn, leaving Django hanging.

This is still just a theory, but it is a very common problem and hopefully leads you and any others experiencing similar problems, to the right place.

Upvotes: 0

Eddwin Paz
Eddwin Paz

Reputation: 2868

We will use a .sh file to start the gunicorn process. Later you will use a supervisord configuration file. what is supervisord? some external know how information link about how to install supervisord with Django,Nginx,Gunicorn Here

gunicorn_start.sh remember to give chmod +x to the file.

#!/bin/sh
NAME="myDjango"
DJANGODIR="/var/www/html/myDjango"
NUM_WORKERS=3
echo "Starting myDjango -- Django Application"
cd $DJANGODIR
exec gunicorn -w $NUM_WORKERS $NAME.wsgi:application --bind 127.0.0.1:8001

mydjango_django.conf : Remember to install supervisord on your OS. and Copy this on the configuration folder.

[program:myDjango]
command=/var/www/html/myDjango/gunicorn_start.sh
user=root
autorestart=true
redirect_sderr=true

Later on use the command:

Reload the daemon’s configuration files, without add/remove (no restarts)

supervisordctl reread

Restart all processes Note: restart does not reread config files. For that, see reread and update.

supervisordctl start all

Get all process status info.

supervisordctl status 

Upvotes: 1

Yonsy Solis
Yonsy Solis

Reputation: 964

In my case I deploy in Ubuntu servers (LTS releases, now almost are 14.04 LTS servers) and I never did have problems with gunicorn daemons, I create a gunicorn.conf.py and launch gunicorn with this config from upstart with an script like this in /etc/init/djangoapp.conf

description "djangoapp website"
start on startup
stop on shutdown
respawn
respawn limit 10 5

script
  cd /home/web/djangoapp
  exec /home/web/djangoapp/bin/gunicorn -c gunicorn.conf.py -u web -g web djangoapp.wsgi
end script

I configure gunicorn with a .py file config and i setup some options (details below) and deploy my app (with virtualenv) in /home/web/djangoapp and no problems with zombie and orphans gunicorn processes.

i verified your options, timeout can be a problem but another one is that you don't setup max-requests in your config, by default is 0, so, no automatic worker restart in your daemon and can generate memory leaks (http://gunicorn-docs.readthedocs.org/en/latest/settings.html#max-requests)

Upvotes: 1

Related Questions