原创:杂谈_浅谈 nginx,gunicorn,flask 差别比对
角色划分
flask(django):Python 的 Web 应用程序(如 Flask,django)
nginx:web 服务器,用户角度间接对接应用, 申请响应的 request-response 出入口
WSGI(Web Server Gateway Interface),翻译为 Python web 服务器网关接口,即 Python 的 Web 应用程序(如 Flask)和 Web 服务器 (如 Nginx) 之间的一种通信协议。也就是说,如果让你的 Web 利用在任何服务器上运行,就必须遵循这个协定。
几种部署形式差别
Flask 内置 WebServer + Flask App = 弱鸡版本的 Server, 单过程(单 worker) / 失败挂掉 / 不易 Scale
Gunicorn + Flask App = 多过程(多 worker) / 多线程 / 失败主动帮你重启 Worker / 可简略 Scale
多 Nginx + 多 Gunicorn + Flask App = 小型多实例 Web 利用,个别也会给 gunicorn 挂 supervisor
为何 gunicorn
简略来说 flask 自带 server 太弱了(几个申请就打满了)。
2 大缺点
『单 Worker』只有一个过程在跑所有的申请,而因为实现的简陋性,内置 webserver 很容易卡死。并且只有一个 Worker 在跑申请。在多核 CPU 下,仅仅占用一核。当然,其实也能够多起几个过程。『不足 Worker 的治理』接上,退出负载量上来了,Gunicorn 能够调节 Worker 的数量。而这个货色,内置的 Webserver 是不适宜做这种事件的。
Gunicorn 作为 Server 相对而言的晋升。
帮我 scale worker, 过程挂了帮我重启
用 python 的框架 flask/django/webpy 配置起来都差不多。还有信号机制。能够反对多种配置。其余:在治理 worker 上,应用了 pre-fork 模型,即一个 master 过程治理多个 worker 过程,所有申请和响应均由 Worker 解决。Master 过程是一个简略的 loop, 监听 worker 不同过程信号并且作出响应。比方承受到 TTIN 晋升 worker 数量,TTOU 升高运行 Worker 数量。如果 worker 挂了,收回 CHLD, 则重启失败的 worker, 同步的 Worker 一次解决一个申请。
为何 nginx
01, 负载平衡。tornado 之类的框架只反对单核,所以多过程部署须要反向负载平衡。gunicorn 自身就是多过程其实不须要
02, 动态文件反对,通过配置之后,nginx 能够间接解决动态文件申请而不必通过 Python 服务器,Python 服务器也能够返回非凡的 http01, 头将申请 rewrite 到动态文件。我说的是通过配置之后,你配置了吗?
03, 抗并发压力。尽管不能晋升 qps,然而多一层前端,确实能够排汇一些刹时的并发申请,让 nginx 先放弃住连贯,而后后端缓缓消化,但说实话这种状况下服务体验曾经很蹩脚了。但确实比服务挂掉强一些。
04,rewrite 之类的其余性能。配置了才有,配了吗?
服务器和客户端的通信,咱们简略的分为三个局部:request,request handling,和 response,即客户端向服务器发动申请,服务器端响应并解决申请,和将申请后果返回客户端,这三个过程。
对于 Web 网站或服务而言,因为 request 和 response 延时是不可控的,咱们须要在思考解决高提早客户端申请的状况。这些申请会占据服务器端的过程。
Nginx 这类异步的服务器软件善于用很少的内存和 cpu 开销来解决大量的申请。因为他们擅长于同时解决大量客户端申请,所以慢客户端申请对他们影响不大
所以把 Nginx 挡在 pre-forking 服务后面解决申请是一种很好的抉择。
Nginx 可能异步、高并发的响应客户端 request(慢客户端申请对 Nginx 影响不大),Nginx 一旦接管到的申请后立即转给 Gunicorn 服务解决,处理结果再由 Nginx 以 response 的模式发回给客户端。这样,整个服务端和客户端的通信,就由原来仅通过 Gunicorn 的同步通信,变成了基于 Nginx 和 Gunicorn 的异步通信,通信效率和并发能力失去大大晋升。
对于网站而言,除了要思考下面介绍的状况,还要思考各种动态文件的托管问题。动态文件既包含 CSS、JavaScript 等前端文件,也包含图片、视频和各类文档等,所以动态文件要么可能会比拟大,要么会调用比拟频繁,动态文件的托管性能,就是要保障 各类动态能失常的加载、预览或下载,这其实就是 Response 耗时长的“慢客户端行为”。用 Gunicorn 托管动态文件,也会重大影响 Gunicorn 的响应效率,而这恰好又是 Nginx 善于的工作,所以动态文件的托管也交给 Nginx 搞定就好。
综合
nginx 能够缓冲申请和响应。如果让 Gunicorn 间接提供服务,浏览器发动一个申请,鉴于浏览器和网络状况都是未知的,http 申请的发动过程可能比较慢,而 Gunicorn 只能期待申请发动实现后,才去真正解决申请,解决实现后,等客户端齐全接管申请后,才持续下一个。
nginx 缓存客户端发动的申请,直到收残缺个申请,转发给 Gunicorn,等 Gunicorn 解决实现后,拿到响应,再发给客户端,这个流程是 nginx 善于解决,而 Gunicorn 不善于解决的。
因而将 Gunicorn 置于 nginx 前面,能够无效进步 Gunicorn 的解决能力。
参考
[线上环境部署 Django,nginx+uwsgi 和 nginx+gunicorn,这两种计划,应该如何抉择?]:https://www.jianshu.com/p/be2…
Nginx、Gunicorn 在服务器中别离起什么作用?:https://www.zhihu.com/questio…
nginx+uwsgi 和 nginx+gunicorn 区别、如何部署:https://www.jianshu.com/p/be2…