您的位置:首页 > 其它

uWSGI详解

2016-05-09 17:49 393 查看


WSGI是什么?

WSGI,全称WebServerGatewayInterface,或者PythonWebServerGatewayInterface,是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。

WSGI的官方定义是,thePythonWebServerGatewayInterface。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。

WSGI是作为Web服务器与Web应用程序或应用框架之间的一种低级别的接口,以提升可移植Web应用开发的共同点。WSGI是基于现存的CGI标准而设计的。

很多框架都自带了WSGIserver,比如Flask,webpy,Django、CherryPy等等。当然性能都不好,自带的webserver更多的是测试用途,发布时则使用生产环境的WSGIserver或者是联合nginx做uwsgi。

也就是说,WSGI就像是一座桥梁,一边连着web服务器,另一边连着用户的应用。但是呢,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进行处理。WSGI
的作用如图所示:




WSGI的作用

WSGI有两方:“服务器”或“网关”一方,以及“应用程序”或“应用框架”一方。服务方调用应用方,提供环境信息,以及一个回调函数(提供给应用程序用来将消息头传递给服务器方),并接收Web内容作为返回值。

所谓的WSGI中间件同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用:从WSGI服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。“中间件”组件可以执行以下功能:

重写环境变量后,根据目标URL,将请求消息路由到不同的应用对象。

允许在一个进程中同时运行多个应用程序或应用框架。

负载均衡和远程处理,通过在网络上转发请求和响应消息。

进行内容后处理,例如应用XSLT样式表。

WSGI的设计确实参考了Java的servlet。

接下来,我们要介绍的是uWSGI。


uWSGI

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

要注意WSGI/uwsgi/uWSGI这三个概念的区分。

WSGI看过前面小节的同学很清楚了,是一种通信协议。

uwsgi同WSGI一样是一种通信协议。

而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。

uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(typeofinformation),每一个uwsgipacket前4byte为传输信息类型描述,它与WSGI相比是两样东西。
为什么有了uWSGI为什么还需要nginx?因为nginx具备优秀的静态内容处理能力,然后将动态内容转发给uWSGI服务器,这样可以达到很好的客户端响应。

接下来,我们要看看
uWSGI的安装配置与使用。


安装

uWSGI的安装很简单:

1
pip
install
uwsgi
现在我们试下将Django跑起来。我们先在virtualenv创建一个DjangoProject:

1
[root@nowamagic
~]
#
cdnowamagic_venv
2
[root@nowamagic
nowamagic_venv]
#
sourcebin/activate
3
(nowamagic_venv)[root@nowamagic
nowamagic_venv]
#
django-admin.pystartprojectnowamagic_pj
virtualenv的路径与目录文件如下:



Django
Project的路径与目录文件如下:




测试uwsgi

在你的服务器上写一个test.py:

1
#
test.py
2
def
application(env,
start_response):
3
start_response(
'200
OK'
,
[(
'Content-Type'
,
'text/html'
)])
4
return
"Hello
World"
我的test.py的路径是/root/nowamagic_venv/nowamagic_pj/test.py,执行以下命令:

1
[root@nowamagic
~]
#
cdnowamagic_venv
2
[root@nowamagic
nowamagic_venv]
#
sourcebin/activate
3
(nowamagic_venv)[root@nowamagic
nowamagic_venv]
#
uwsgi--http:8001--wsgi-file/root/nowamagic_venv/nowamagic_pj/test.py
访问网页http://115.28.0.89:8001/,OK,显示HelloWorld,说明uwsgi安装成功。


测试你的Django项目

前面我们用django-admin.pystartprojectnowamagic_pj创建了一个项目,现在我们用Django自带的Web服务器看看我们的项目有没出问题。还是进入我们虚拟环境:

1
[root@nowamagic
~]
#
cdnowamagic_venv
2
[root@nowamagic
nowamagic_venv]
#
sourcebin/activate
3
(nowamagic_venv)[root@nowamagic
nowamagic_venv]
#
python2.7/root/nowamagic_venv/nowamagic_pj/manage.pyrunserver0.0.0.0:8002
执行这个命令报错:Nomodulenameddjango.core.management,原因应该是装了多个版本的Python导致的。命令指定文件路径就行,丑是丑些了:

viewsource

print?

1
(nowamagic_venv)[root@nowamagic
nowamagic_venv]
#
/usr/local/bin/python2.7/root/nowamagic_venv/nowamagic_pj/manage.pyrunserver0.0.0.0:8002
OK,启动Django自带的服务器了,我们再访问http://115.28.0.89:8002/,成功显示:


说明Djanggo项目也没问题。


连接Django和uwsgi

最后一步了,我们要把uwsgi与Django连接起来。

编写django_wsgi.py文件,将其放在与文件manage.py同一个目录下。我的放在/root/nowamagic_venv/nowamagic_pj/下:

viewsource

print?

01
#!/usr/bin/env
python
02
#
coding:utf-8
03
04
import
os
05
import
sys
06
07
#
将系统的编码设置为UTF8
08
reload
(sys)
09
sys.setdefaultencoding(
'utf8'
)
10
11
os.environ.setdefault(
"DJANGO_SETTINGS_MODULE"
,
"nowamagic_pj.settings"
)
12
13
from
django.core.handlers.wsgi
import
WSGIHandler
14
application
=
WSGIHandler()
注意不要直接copy,有个地方要改:注意到语句os.environ.setdefault。比如我的项目为nowamagic_pj,则语句应该是
os.environ.setdefault("DJANGO_SETTINGS_MODULE","nowamagic_pj.settings")

OK,进入虚拟环境执行指令:

1
[root@nowamagic
~]
#
cdnowamagic_venv
2
[root@nowamagic
nowamagic_venv]
#
sourcebin/activate
3
(nowamagic_venv)[root@nowamagic
nowamagic_venv]
#
uwsgi--http:8000--chdir/root/nowamagic_venv/nowamagic_pj/--moduledjango_wsgi
成功显示DjangoItWorks页面。

这样,你就可以在浏览器中访问你的Django程序了。所有的请求都是经过uwsgi传递给Django程序的。
这里我们介绍了如何把uwsgi与Django连接起来,在下一篇将继续介绍如何将uwsgi与Nginx连接。

上一篇介绍了uWSGI来部署Django程序,但在在生产环境中单单只有uWSGI是不够的,Nginx是必不可少的工具。

先安装Nginx,可以参照前面的小节:使用RPM安装Nginx。


Nginx配置

在nginx.conf上加入/修改,我的server配置如下(一切从简……):

01
server
{
02
listen
80
;
03
server_name
115.28
.
0.89
;
04
#server_name
localhost;
05
06
access_log
/
home
/
nowamagic
/
logs
/
access.log;
07
error_log
/
home
/
nowamagic
/
logs
/
error.log;
08
09
#root
/root/nowamagic_venv/nowamagic_pj;
10
location
/
{
11
uwsgi_pass
127.0
.
0.1
:
8077
;
12
#include
uwsgi_params;
13
include
/
etc
/
nginx
/
uwsgi_params;
14
#uwsgi_pass
127.0.0.1:8077;
15
#uwsgi_param
UWSGI_SCRIPTindex;
16
#uwsgi_param
UWSGI_PYHOME$document_root;
17
#uwsgi_param
UWSGI_CHDIR$document_root;
18
}
19
access_log
off;
20
}
注意保证配置里写的目录/home/nowamagic/logs/和/home/nowamagic/logs/存在,接下来就没啥问题了,Nginx配置很简单。


uWSGI配置

前面我们是直接使用命令行来启动uWSGI,在实际部署环境中,我们常用的是配置文件的方式,而非命令行的方式。

我的Django程序目录:/root/nowamagic_venv/nowamagic_pj/

这里让Nginx采用8077端口与uWSGI通讯,请确保此端口没有被其它程序采用。

uWSGI支持多种配置文件格式,比如xml,ini,json等等都可以。

1.xml配置

请确定你在上一节中的django_wsgi.py文件已经存在了。新建一个XML文件:nowamagic_pj.xml,将它放在/root/nowamagic_venv/nowamagic_pj目录下

01
<uwsgi>
02
<socket>
127.0
.
0.1
:
8077
<
/
socket>
03
<listen>
80
<
/
listen>
04
<master>true<
/
master>
05
<pythonpath>
/
root
/
nowamagic_venv
/
nowamagic_pj<
/
pythonpath>
06
<processes>
1
<
/
processes>
07
<logdate>true<
/
logdate>
08
<daemonize>
/
var
/
log
/
uwsgi.log<
/
daemonize>
09
<plugins>python<
/
plugins>
10
<
/
uwsgi>
然后执行命令:

1
uwsgi
-x/root/nowamagic_venv/nowamagic_pj/nowamagic_pj.xml
2
or
3
/usr/
local
/bin/uwsgi
-x/root/nowamagic_venv/nowamagic_pj/nowamagic_pj.xml
加载指定的xml配置文件。当使用命令行参数时,可以使用简化命令“-x”。当然也可以不简写:

1
uwsgi
--xml/etc/nowamagic.xml
甚至如果在命令行的最后一个参数以“.xml”结尾,那么就隐含将加载该xml文件作为配置。

1
uwsgi
/etc/nowamagic.xml
有时候因各种环境问题,-x--xml命令识别不了,可以使用下面的ini配置方式:

2.ini配置

01
[uwsgi]
02
vhost
=
false
03
plugins
=
python
04
socket
=
127.0
.
0.1
:
8077
05
master
=
true
06
enable
-
threads
=
true
07
workers
=
1
08
wsgi
-
file
=
/
root
/
nowamagic_venv
/
nowamagic_pj
/
nowamagic_pj
/
wsgi.py
09
virtualenv
=
/
root
/
nowamagic_venv
10
chdir
=
/
root
/
nowamagic_venv
/
nowamagic_pj
然后执行命令:

1
uwsgi
--ini/root/nowamagic_venv/nowamagic_pj.ini&
uwsgi这样就启动起来了。如果无意外的话,就能在网上访问你的Python项目了。


小插曲

我在配置完Nginx和uWSGI之后,访问时显示502错误。查看uWSGI启动信息,发现这么一条:ImportError:Nomodulenameddjango.core.wsgi。

然后推断,我的CentOS上的Python版本是2.4.3,然后进入virtualenv,执行:

1
python
2
<<<
import
django
3
<<<
from
django.core.wsgi
import
get_wsgi_application
4
<<<
则没报错,因为我的虚拟环境里的Python版本是2.7.5。推断成立,但是虚拟环境里的Django会默认调用外部环境的Python。解决方法:在虚拟环境里pipinstalldjango。

OK,问题解决,一切正常。


一些我在配置时用到的命令,省得你去搜索:

1.关闭uWSGI:

1
killall
-9uwsgi
2
killall
-sHUP/var/www/uwsgi
3
killall
-sHUP/usr/
local
/bin/uwsgi
2.列出端口占用情况:

1
netstat
-lpnt
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: