Nginx,uWSGI与Django 应用的关系

前因

       关于WSGI、uWSGI、uwsgi、Nginx这些名词及与Django 项目的关系,之前有个善(漂)良(亮)的小姐姐问过我,当时我也不是很明白,没有给她解释的很清楚,很是后悔,现在结合网上的一些资料进行一下汇总,且加入了一些我自己的看法,有不足之处还望路过的大佬给予批评指正,拜谢!

名词介绍

WSGI (通信协议)

全称Web Server Gateway Interface(Web服务器网关接口),它不是服务器、Python模块、框架、API或者任何软件,只是一种描述Web 服务器(如nginx,uWSGI 等服务器)如何与Web 应用程序(如用Django、Flask框架写的程序)通信的规范,是一种实现了比如Python 解析的通用接口标准/标准,实现了Python Web 程序与服务器交互的通用性,利用这个协议,Web 项目就可以轻松部署在不同的Web Server 上了。

uWSGI(服务器)

uWSGI 是一个全功能的HTTP 服务器,实现了WSGI 协议、uwsgi协议、http协议等,它要做的就是把HTTP协议转化成语言支持的网络协议,比如把HTTP协议转换成WSGI 协议,让Python 可以直接使用。

uwsgi(线路协议)

与WSGI 一样,是uWSGI服务器的独占通信协议,用于定义传输信息的类型(type of information)。每一个uwsgi packet 前4 byte 为传输信息类型的描述,与WSGI 协议是两种东西,据说该协议是fcgi协议的10倍快。

Nginx

Nginx 是一个开源的高性能的HTTP 服务器和反向代理,具体作用:
1.可以作为web 服务器,处理静态文件和索引文件效率非常高;
2.它的设计非常注重效率,最大支持5万个并发连接,但是只占用很少的内存空间;
3.稳定性高,配置简洁;
4.还可以用于强大的反向代理和负载均衡功能,平衡集群中各个服务器的负载压力应用。

很多资料上都有的一句话,交代了这几个名词的关系:uWSGI 服务器实现了WSGI协议,uwsgi协议,http协议等等,Nginx 中的HttpUwsgiModule 的作用是与uWSGI 服务器进行交换。

以Django 框架开发为例

Django

Django 是一个Web框架,框架的作用在于处理request 和response,其他的不是框架所关心的内容,所以如何部署Django 也不是Django 所需要关心的。
Django 所提供的是一个开发服务器,这个开发服务器,没有经过安全测试,而且使用的是Python 自带的simple HTTPServer 创建的,如果你看了Django 源码就知道,runserver 起来的HTTPServer 就是Python 自带的simple HTTPServer,所以在安全性和效率上都是不行的。

在Django 开发的Web 应用程序中,nginx和uWSGI 服务器之间是如何配合工作的?

1.首先客户端发送http 请求,来获取服务器资源;
2.Nginx 作为直接对外的服务器接口,接收到客户端发过来的http请求,然后进行解包、分析;
3.如果是静态资源的请求,会根据nginx 配置的静态文件目录,返回请求的资源;
4.如果是动态资源的请求,nginx 就会通过配置,将请求传递给uWSGI 服务器;
5.uWSGI 将接收到的数据包进行处理,并转发给WSGI(HTTP 协议转成WSGI 协议);
6.WSGI 根据请求调用Django 项目中的某个文件或函数,进行逻辑处理,完成后Django 将返回值交给WSGI;
7.WSGI 将返回值打包,转发给uWSGI 服务器(WSGI 协议转换成HTTP 协议);
8.uWSGI 服务器接收后转发给Nginx 服务器,最终Nginx 服务器将返回值返回给客户端(如浏览器)
注意:不同的组件之间传递信息涉及到数据格式和协议的转换

关于Nginx

1.第一级的Nginx 并不是必须的,uwsgi 完全可以完成整个和浏览器交互的流程;
2.在Nginx 上加上安全性或其他得限制,可以达到保护程序的作用;
3.uWSGI 本身是内网接口,开启多个work 和processes 可能也不够用,而Nginx 可以代理多台uWSGI 完成uWSGI 负载均衡;
4.Django 在Debug=Flase 下对静态文件的处理能力不是很好,而用Nginx 来处理会更加高效

       一个成熟的站点提供服务,需要Web 服务器(静态数据)和APP 服务器(动态数据)。Web 服务器目前属Nginx 最强大,用户请求代理过来后,把静态数据返回给客户端。但是目前的互联网发展时代,都是包含动态数据处理的,Nginx 不处理业务逻辑,都外包给后端的APP 服务器,比如Django 框架开发的服务器。

       再需要性能优化的场景,单单通过Nginx 和uWSGI 也是不够的,Nginx 主要的优化是连接数和处理静态资源的请求,uWSGI 主要优化的是WSGI 服务,这些都只是手段,其他手段包括:优化数据库、增加缓存、加入负载均衡、引入异步IO 框架(如gunicorn 服务器的gevent 框架)、计算密集型模块用C 重写等。安全性方面,也有很多考虑,原作者没有展开介绍:)

扩展

下面是我之前截图的一个大佬自己测试的各种配置的性能对比,原帖暂时找不到,如果大佬看见了,请在下面留言,我会根据您的要求,添加或删除这部分资料,谢谢


1.Django

毫无疑问,用原生Django 的Server 做处理的表现是最烂的(上面介绍了,Django 原生的Server 就是Python 自带的simple HTTPServer 创建的),在10000 次请求的情况下,broken pipe (就是请求失败吧)的几率极高,只有1400次请求被处理,成功了只有14%,原作者懒得继续测下去了(以后有机会我也测试测试)。


2.Django + Nginx

这次搭上了Nginx 做反向代理,也使得脆弱的Django 服务器的情况有所缓解,但成功率仍然不高(10000 次请求中有3684 个请求被处理)。


3.uWSGI + Nginx

uWSGI 是性能极高的一个由C 编写的服务器,使用了自身独占的uwsgi 协议,这次让它配合Nginx 处理Django 的request,参数为4 进程 + 2 线程,性能立即直线商城,处理请求的成功率也基本在90% 左右,原作者在测试的时候遇到了一个坑,就是uWSGI 在处理请求的时候发送了队列溢出的问题,因为当前测试设置的并发数为每秒1000 次并发,而uWSGI 的处理队列的容量默认是100*(启动的uWSGI 的进程数),导致处理请求的时间加长,而这个问题则可以通过修改somaxcon 的大小解决(具体做法在5 个配置下面 ),总的来说,使用uWSGI + Nginx 是一个理想的选择。


4.Gunicorn + Nginx

gunicorn 跟 uWSGI 类似,也是一个高性能的http 服务器,它由ruby 的unicorn 项目移植,是由Python 编写的,它的配置简单,而且可以灵活的搭配其他网络库,部署十分方便,在测试数据中可以看到,用这种配置运行Django 能在短时间内就能处理大量的并发请求,成功率在90% 左右。
(我们之前这种配置都是配置Flask 框架开发的Web 服务器)


5.Gunicorn + Nginx +Gevent

前面说的几种环境,看似不错,但是作者说了,我们需要追求完美!由于gunicorn 是同步(sync)单线程模型的,有时候不免会发生一些阻塞问题,这时候我们为gunicorn 加上 -k gevent 参数来用gevent 做处理接口,这就比较靠谱的处理了阻塞问题,从作者的测试结果可以得到,这种模式下不仅拥有100% 的处理成功率,而且时间也在很短之内完成,是5组测试数据当中性能最好的!
补充一句:原作者好棒!

uWSGI listen queue 队列溢出的修补措施:

1.修改系统参数
vim /etc/sysctl.conf
在文件最后添加一行记录net.core.somaxcon = 1024
执行sysctl -p重新load参数设置,这样会立即生效,并且以后重新启动机器也会生效。

2.设置uwsgi启动的--listen 1024.
这样 你的机器并发数就可以得到一个很大的提升。

参考:

1.百度百科

2.uWSGI + django + nginx 的工作原理流程与部署历程:https://blog.csdn.net/c465869935/article/details/53242126

3.uWSGI listen queue 队列溢出的问题:http://www.cnblogs.com/zhujie/archive/2012/04/27/2474051.html


原文地址:https://www.cnblogs.com/yungiu/p/10387362.html