Post on 17-May-2015
Production-grade Servers for Django
DjangoDay 2012Roberto De Ioris (Unbit)
giovedì 26 aprile 12
python manage.py runserver
Why not ?
giovedì 26 aprile 12
Availability
crash happens. always.
giovedì 26 aprile 12
Concurrency
there is no “premature optimization” thing in sysadmins world
giovedì 26 aprile 12
Users
They ignore you when things go well. They hate you when things go wrong. They want to kill you a bunch
of minutes later...
giovedì 26 aprile 12
Servers are a cost
...and can became the higher cost very easily
giovedì 26 aprile 12
The manager want to scale
...even if he does not know what it means
giovedì 26 aprile 12
Security
be ready for the truth
giovedì 26 aprile 12
WSGI
one standard to rule them all...
def application(env, start_response):
start_response(‘200 OK’, [(‘Content-Type’,‘text/html’)])
return “Hello World”
giovedì 26 aprile 12
Proxy servers and static contents
do not expose your app to the world. NEVERdo not serve static !les with Django. NEVER
giovedì 26 aprile 12
app
appwebserver
app
world
giovedì 26 aprile 12
Once upon a time...
Flup and mod_python
giovedì 26 aprile 12
Flup
FastCGI, SCGI, AJPpure python, preforking-multithread
giovedì 26 aprile 12
mod_python
was a bad idea ?
giovedì 26 aprile 12
The new generation
mod_wsgigunicorn
uWSGI
giovedì 26 aprile 12
mod_wsgiapache module (in C)
2 modes: embedded and daemon
preforking and multithread
mature
solid
Windows support
giovedì 26 aprile 12
# mod_wsgi config
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.pyWSGIPythonPath /path/to/mysite.com
WSGIDaemonProcess pippo processes=2 threads=15
<Directory /path/to/mysite.com/mysite> <Files wsgi.py> Order deny,allow Allow from all </Files></Directory>
giovedì 26 aprile 12
gunicorn
pure python
do one thing do it well
preforking (+async extensions)
speaks http
easy (maybe the easiest tool ever written)
giovedì 26 aprile 12
PYTHONPATH=/var/www gunicorn --workers 2 --bind 127.0.0.1:8000 pippo.wsgi:application
# or add gunicorn to INSTALLED_APPS# it will bind to port 8000
python manage.py run_gunicorn
giovedì 26 aprile 12
uWSGIpure C
preforking + multithread + async + plugins + blah blah
feature rich (a blast beat of options)
speaks uwsgi,FastCGI,Mongrel2-zeromq,HTTP and maybe Klingon
fat-beardy-braces_equipped sysadmin friendly
high learning curve
made only for making money
Mr Wolf would wear a uWSGI t-shirt
giovedì 26 aprile 12
uwsgi --http-socket 127.0.0.1:8000 --wsgi-!le /var/ww/pippo/wsgi.py --processes 2 --threads 15
# or
[uwsgi]http-socket = 128.0.0.1:8000wsgi-!le = /var/ww/pippo/wsgi.pyprocesses = 2threads = 15
# or
<uwsgi> <http-socket> 128.0.0.1:8000</http-socket> <wsgi-!le> /var/ww/pippo/wsgi.py</wsgi-!le> <processes>2</processes> <threads>15</threads></uwsgi>
#or .....
giovedì 26 aprile 12
before you ask...
speed is not a problem
giovedì 26 aprile 12
Which One?
no easy answers...but...
giovedì 26 aprile 12
DO NOT LOOK AT BENCHMARKS
...otherwise you will directly go with uWSGI...
giovedì 26 aprile 12
Newbie ?
gunicorn is the easiest choice
giovedì 26 aprile 12
need full apache integration ?
mod_wsgi FTW
giovedì 26 aprile 12
want a full stack ?
uWSGI has no competitors
giovedì 26 aprile 12
on the cloud ?
gunicorn and uWSGI all over the place
giovedì 26 aprile 12
still confused ?
gunicornuWSGI
mod_wsgi
giovedì 26 aprile 12
other choices ?
a lot...
Tornado
Passenger
fapws3
...
giovedì 26 aprile 12
Questions ?
giovedì 26 aprile 12