Nginx、Gunicorn在服务器中分别起什么作用?
嗯,怎么说呢,大部分人在gunicorn前面部署一层nginx的时候也的确没有想过为什么,他们只是觉得这样显得他们比较专业,而且幻想着加了一层nginx反向代理之后性能会有提升,恕我直言,请你们带上脑子,一个单纯的串联结构怎么可能提升性能?请好好想一想这个问题好吗?
在前面增加一层nginx的情况主要是:
因此将Gunicorn置于nginx后面,可以有效提高Gunicorn的处理能力
在前面增加一层nginx的情况主要是:
- 负载均衡。tornado之类的框架只支持单核,所以多进程部署需要反向负载均衡。gunicorn本身就是多进程其实不需要
- 静态文件支持,经过配置之后,nginx可以直接处理静态文件请求而不用经过Python服务器,Python服务器也可以返回特殊的http头将请求rewrite到静态文件。我说的是经过配置之后,你配置了吗?
- 抗并发压力。虽然不能提升qps,但是多一层前端,的确可以吸收一些瞬时的并发请求,让nginx先保持住连接,然后后端慢慢消化,但说实话这种情况下服务体验已经很糟糕了。但的确比服务挂掉强一些。
- rewrite之类的其他功能。配置了才有,配了吗?
- 怕gunicorn的http解析有bug。这个姑且算有点道理,不过加一层负载均衡不一定能解决问题。
主要来说加一层可以给你一些你很可能不会去配置的额外的功能,这样多少会给运维人员一些安慰,反正也不会有什么性能损耗,也就是说不太会有坏处,所以大家都假装自己很懂地加了一层反向负载均衡。其实不见得就没有坏处,比如说可能会获取不到对端IP地址(变成127.0.0.1了),或者可能会被X-Forwarded-For欺骗。
不过另一个角度来说,如果你的业务早晚会上规模,早晚有一天会用上反向负载均衡,提前配一个也对,不过应该用两台服务器,配在不同服务器上。内部服务的情况下如果压力不太大,很多其实都是gunicorn裸跑的,Python不是PHP,不用非得加个前端。
如果
- 只有一个应用,不需要负载均衡
- 只提供api服务,没有静态文件
- 不需要额外的访问控制等功能
这样是不是就不需要nginx等反向代理?
答案是需要。
nginx可以缓冲请求和响应。如果让Gunicorn直接提供服务,浏览器发起一个请求,鉴于浏览器和网络情况都是未知的,http请求的发起过程可能比较慢,而Gunicorn只能等待请求发起完成后,才去真正处理请求,处理完成后,等客户端完全接收请求后,才继续下一个。
nginx缓存客户端发起的请求,直到收完整个请求,转发给Gunicorn,等Gunicorn处理完成后,拿到响应,再发给客户端,这个流程是nginx擅长处理,而Gunicorn不擅长处理的。
因此将Gunicorn置于nginx后面,可以有效提高Gunicorn的处理能力
不套Gunicorn 也可以做到外网访问,那为什么还要套呢?是一样的道理。
Nginx 是专业的服务器,性能更好,更专业,并发更高,可以做负载均衡,可以做静态文件缓存,还可以限制 ip 访问的频率等等。
Gunicorn 一般用来管理多个进程,有进程挂了Gunicorn可以把它拉起来,防止服务器长时间停止服务,还可以动态调整 worker 的数量,请求多的时候增加 worker 的数量,请求少的时候减少,这就是所谓的 pre-fork 模型,这貌似就是它的主要优点。(worker 貌似就是进程,不是很确定,因为我们在使用的过程中没有发现进程数量有变化。。。)
也可以用 supervisor 来启动 Gunicorn,这样即使Gunicorn 的管理进程挂了也可以自动起来。
Nginx 是专业的服务器,性能更好,更专业,并发更高,可以做负载均衡,可以做静态文件缓存,还可以限制 ip 访问的频率等等。
Gunicorn 一般用来管理多个进程,有进程挂了Gunicorn可以把它拉起来,防止服务器长时间停止服务,还可以动态调整 worker 的数量,请求多的时候增加 worker 的数量,请求少的时候减少,这就是所谓的 pre-fork 模型,这貌似就是它的主要优点。(worker 貌似就是进程,不是很确定,因为我们在使用的过程中没有发现进程数量有变化。。。)
也可以用 supervisor 来启动 Gunicorn,这样即使Gunicorn 的管理进程挂了也可以自动起来。
1.负载均衡,nginx占用80端口,g可以占用多个非80端口;
2.拦截静态请求;
3.伪静态化并缓存,减少动态请求数量;
4.依赖于nginx强大的功能和性能,可以做访问控制,限速,限连接数等等;
2.拦截静态请求;
3.伪静态化并缓存,减少动态请求数量;
4.依赖于nginx强大的功能和性能,可以做访问控制,限速,限连接数等等;