本篇博文解答两个问题:
- 在FLASK项目部署时为什么需要使用服务器软件:Gunicorn和Nginx。
- Gunicorn和Nginx都是服务器软件,单独使用Gunicorn也可以提供web服务,为什么还要再套一层Nginx呢?
先来解决第一问题:在FLASK项目部署时为什么需要使用服务器软件:Gunicorn和Nginx。裸跑不可以吗?
在开发环境下裸跑是可以的,但是在生成环境下绝对不行。
因为Flask 是一个web框架,而非web server,直接用Flask裸跑提供的web服务在生产环境不够稳定,也无法承受大量请求的并发,生产环境下需要服务器软件来处理各种请求,其中”Gunicorn+Nginx“是一个很不错的选择!
第二个问题:Gunicorn和Nginx都是服务器软件,单独使用Gunicorn也可以提供web服务,为什么还要再套一层Nginx呢?
相信这个问题对很多初学者来说很迷惑,下面是我个人的一点拙见。
Gunicorn之外再套一层Nginx有诸多作用:
1.防止”慢客户端行为“带来的性能降低
Gunicorn(绿色独角兽)是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server,具有实现简单,轻量级,高性能等特点。
Gunicorn有3种并发方式:workers模式、多线程模式、伪线程模式。
虽然Gunicorn具有高性能的特点,但是在生产环境下的Gunicorn无法避免”慢客户端行为“带来的性能降低问题。
这里解释一下慢客户端行为:
客户端和服务端的通信可简略地分为三个阶段:request,request handling,和response,即客户端向服务器发起请求,服务器端响应并处理请求,和将请求结果返回客户端,这三个过程。
request handling阶段的耗时取决于服务器性能,通常情况下这一阶段是比较高效的,耗时较少。而request阶段和response阶段与客户端相关,影响耗时的多少的因素较多。这三个过程放到同一个进程中同步处理时,如果request和response部分耗时比较多,会使计算资源被占据并无法及时释放,导致计算资源无法有效利用,降低服务器的处理能力。”慢客户端行为“指的就是request或response部分耗时较多的情况。
Gunicorn工作在workers并发方式时,一个同步的worker进程一次处理一个请求,而且worker的数量是有限的,当慢客户端向服务器发出的请求多于服务器可用的worker进程时,由于这些慢客户端请求会占据服务端worker进程,服务器端没有更多worker进程响应新的请求,新的请求只能等待有进程被释放掉后,才能得到响应,因此Gunicorn在面对”慢客户端行为“时响应效率就会降低很多。
Nginx能够异步、高并发的响应客户端request(慢客户端请求对Nginx影响不大),Nginx缓存客户端发起的请求,直到收完整个请求,转发给Gunicorn处理,处理结果再由Nginx以response的形式发回给客户端。这样,整个服务端和客户端的通信,就由原来仅通过Gunicorn的同步通信,变成了基于Nginx和Gunicorn的异步通信,通信效率和并发能力得到大大提升。
2.实现动静分离
Nginx有托管静态文件的功能。对于大量调用频繁,且数据量大的静态文件(CSS、JS、图片等),如果用Gunicorn处理,会使response阶段耗时长,严重影响Gunicorn的效率。将静态文件托管给高效的Nginx,对于静态文件的请求Nginx会直接响应,而不转发给Gunicorn,可以解决上述问题,实现动静分离。
3.其他
Gunicorn之外再套一层Nginx的作用还用很多:例如:1.可以做负载均衡,使Gunicorn水平扩容成为可能;2.依赖于nginx强大的功能和性能,可以做访问控制,限速,限连接数等等。
个人浅见,欢迎补充!
参考文献: