I am new to this, but by comparing the code of gunicorn with flask/werkzeug, I fail to understand the real benefit of inserting gunicorn between nginx and flask. Would like to get some expert opinions on this.
For what I understand so far, it boils down to comparing gunicorn with werkzeug's dev server. In short, I fail to understand why werkzeug's server is called a dev server, while gunicorn is considered prod ready. The argument for choosing gunicorn over werkzeug that I can think of:
- Performance. Gunicorn is based on prefork model, while werkzeug can spin off a thread or process on the fly for each request. But Stevens had a comparison in his UNP book, and prefork was not a clear winner in his tests. Spinning off a thread (not process) on linux should be fairly cheap, without the need to handle the pre-forked process pool. So for CPU bound services, the python GIL makes werkzeug's threading model less attractive, but for IO bound services, werkzeug should be good enough?
- Gunicorn supports gevent/eventlet/tornado, while werkzeug does not. But since asyncio is becoming a native in python 3, these green threads libraries seem less crucial?
- Security? again I am no expert on this, but nginx seems a good defender already? Besides, gunicorn does not seem to provide extra protection in this regard, compared to werkzeug's dev server.
- SSL. Flask and werkzeug server does not seem to handle this. But nginx can handle this already, so flask does not need to?
- Unix socket. Werkzeug's server does not seem to handle unix socket. So if nginx need to forward traffic to backend with unix sockets, either because it's the only way or because it's the most efficient way, then it seems a good argument for gunicorn.
Are the reasons above valid? What are the other reasons?
Btw, I have read SO post 1 and SO post 2 but they do not seem to fully answer my questions yet.