在我们使用Django开发自动化测试平台时,最必不可少的步骤是在服务器上部署它。在开发阶段中,对于Django项目我们使用的web服务器一般都是自带的runserver, 但是runserver从内存和工作效率上来讲是不够的。
要部署Django项目,我们需要挂接到工业用的服务器,最常用方式的则是Nginx uWSGI Django。
Nginx 作为互联网最受欢迎的高性能 http 和 反响代理 Web 服务器,提供静态资源服务、缓存、负载均衡 等功能。
uWSGI 作为对内服务器,处理动态请求,把HTTP协议转化成WSGI协议,让Django可以直接使用。
Django 则是接收请求,并根据请求内容查询数据等资源构建响应数据,把响应结果再次uWSGI。
对于Nginx 以及 Django 的介绍我们已经有过相关介绍的文章,今天给大家介绍这个在Python Web 开发过程中必不可少的uWSGI。
几个基本的概念
我们先明确以下几个概念:
WSGI:全称是Web Server Gateway Interface,WSGI是一种规范,它描述了使用Python编写的web application (比如:Django)与web server(比如:uWSGI)之间通信的规范,实现两者之间的解耦。当前运行在WSGI协议之上的web框架有Bottle, Flask, Django。
Uwsgi:是一种路线协议,是uWSGI服务器的独占协议,用于在uWSGI服务器与其他网络服务器的数据通信。
uWSGI:是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。
它们之间的关系如图所示:
在 Nginx uWSGI Django 中,处理流程则如下图所示:
WSGI 实现
WSGI协议主要包括server和application两部分:
- WSGI server负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端;
- WSGI application接收由server转发的request,处理请求,并将处理结果返回给server。Application中可以包括多个栈式的中间件(middlewares),这些中间件需要同时实现server与application,因此可以在WSGI服务器与WSGI应用之间起调节作用:对服务器来说,中间件扮演应用程序,对应用程序来说,中间件扮演服务器。
WSGI协议其实是定义了一种server与application解耦的规范,即可以有多个实现WSGI server的服务器,也可以有多个实现WSGI application的框架,那么就可以选择任意的server和application组合实现自己的web应用。例如uWSGI和Gunicorn都是实现了WSGI server协议的服务器,Django,Flask是实现了WSGI application协议的web框架,可以根据项目实际情况搭配使用。
下面我们来认识WSGI实现过程:
安装uWSGI:
uWSGI是一个(大的)C应用,因此,你需要一个C编译器 (例如gcc或者clang),以及Python开发头文件。
在基于Debian的发行版上安装:
apt-get install build-essential python-dev |
---|
为Python安装uWSGI:
pip install uwsgi |
---|
使用网络安装器:
curl http://uwsgi.it/install | bash -s default /tmp/uwsgi |
---|
源码安装:
wget http://projects.unbit.it/downloads/uwsgi-latest.tar.gztar zxvf uwsgi-latest.tar.gzcd <dir>make |
---|
一个简单的WSGI应用:
让我们从一个简单最简单的应用开始:
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World"] |
---|
(将其保存为 hello.py)。
它由一个简单的Python函数组成,函数名称为 “application”,它是uWSGI Python加载器将会搜索的默认函数。
应用部署:
现在,启动uWSGI来运行一个HTTP服务器/路由器,它会传递请求到WSGI应用:
uwsgi --http :9090 --wsgi-file hello.py |
---|
添加并发和监控:
可以用 --processes 选项添加更多的进程,或者使用 --threads 选项添加更多的线程 (或者可以同时添加)。
uwsgi --http :9090 --wsgi-file hello.py --master --processes 4 --threads 2 |
---|
这将会生成4个进程 (每个进程有2个线程),一个master进程 (在Inc死掉的时候会生成它们) 和HTTP路由器 。
一个重要的任务是监控。在生产部署上,了解正在发生的事情是至关重要的。stats子系统允许你将uWSGI的内部统计数据作为JSON导出:
uwsgi --http :9090 --wsgi-file hello.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 |
---|
针对的应用发起几次请求,然后telnet到端口9191,可以查看相关信息。
部署在Nginx服务器:
即使uWSGI HTTP路由器是稳定并且高性能的,但是你或许想要将你的应用放在一个全功能的web服务器之后。
uWSGI原生支持HTTP, FastCGI, SCGI及其特定的名为”uwsgi”的协议。最好的协议显然是uwsgi,nginx和Cherokee已经支持它了。
一个常用的nginx配置如下:
location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9090;} |
---|
这表示“传递每一个请求给绑定到9090端口并使用uwsgi协议的服务器”。
现在,我们可以生成uWSGI来本地使用uwsgi协议:
uwsgi --socket 127.0.0.1:9090 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 |
---|
部署Django
Django大概是最常使用的Python web框架了。部署它是相当容易的 (我们继续配置4个进程,每个进程有2个线程)。
假设Django项目位于 /home/web/myproject:
uwsgi --socket 127.0.0.1:9090 --chdir /home/web/myproject/ --wsgi-file myproject/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 |
---|
注:
使用 --chdir ,指定的目录下,在Django中,需要使用它来正确加载模块。
uWSGI支持多种配置风格,我们还可以使用.ini文件(uwsgi.ini):
[uwsgi]socket = 127.0.0.1:9090chdir = /home/web/myproject/wsgi-file = myproject/wsgi.pyprocesses = 4threads = 2stats = 127.0.0.1:9191 |
---|
仅需运行就可完成部署:
uwsgi uwsgi.ini |
---|