https://www.quora.com/What-are-the-differences-between-nginx-and-gunicorn
So, it’s fairly easy to understand how these three pieces fit together, but it’s also important to understand why it’s recommended to connect the pieces in this way. At a high level, Flask is a framework that you build upon to encapsulate the logic of how your respond to a certain HTTP request, gunicorn (or uwsgi) provide an execution environment for this logic to operate in (primarily handling concurrency-related issues) and nginx provides a proxy which has the effect of sheltering that execution environment and providing certain other capabilities (such as serving static requests or routing to different backends based on URL or some other characteristic of the request).
As I said, Flask provides a framework upon which you can build the logic of your application. It specifies that for a given URL, execute this chunk of code, and gives you some scaffolding to handle logic errors, render templates, execute middleware, etc… Flask has a development server with certain features that are useful, like a debugger, but it is only intended to be used in development because it cannot robustly handle a large load of simultaneous requests.
Flask is built upon WSGI (web server gateway interface), which is a specification for the interaction between application logic and a web server. Gunicorn (or uwsgi is the other popular choice for this role) accepts HTTP requests and knows how to call your application logic to get a response. Flask itself can do this in a very rudimentary way intended for low load and development purposes, but Gunicorn is capable of managing concurrency using mechanisms such as threading and event loops. The primary responsibility here is to take an HTTP request and call the corresponding logic code in a robust, concurrent manner. uwsgi is perhaps a better demonstration of this layer because it is much more configurable, it handles request logging, concurrency, worker timeouts, and so much more. But the most important function at this level is robust concurrency.
Finally you have your web proxy layer (called a reverse proxy). Common wisdom says that serving static files from your application layer is a bad idea because it is not optimized for this purpose. Nginx is very well optimized to serving static content; so, you can set up a URL route at the web proxy layer to decide whether a request is for static content or application logic, and either serve the static content or route to the application. Another important function is SSL/TLS termination. Nginx is also very good at doing this (the ‘s’ in https).
But there’s way more to the proxy layer - it is a powerful tool for scalability and protection. Nginx can do load balancing - if your application grows beyond what one server can handle, or if you want more than one for redundancy, Nginx is capable of making one domain route to multiple web servers. Nginx also provides a shield against load spikes and DOS attacks in a few ways. Firstly, it can handle bursts of requests without falling down, and it has a variety of limit mechanisms to help handle traffic spikes (innocent or nefarious); you can block IPs, you can limit the number of allowable backend connections, you can limit request execution times, it can block requests on basically any characteristic of the request (such as user agent or referrer). But really the most important characteristic of Nginx at this layer is its robustness under traffic spikes - it can generally cope with very large amounts of traffic gracefully, and apply the rules and logic you’ve established to handle those circumstances reliably.
So the three layers all serve different roles, Flask encapsulates your logic, your wsgi server handles Python concurrency and the translation from HTTP to Python, and the reverse proxy acts as a gatekeeper, cushion and traffic warden for the wsgi server(s).
网友评论