uWSGI 安装与应用
WSGI是什么?
WSGI(Web Server Gateway Interface,或者 Python Web Server Gateway Interface),是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。自从 WSGI 被开发出来以后,许多其它语言中也出现了类似接口。
WSGI 的官方定义是:the Python Web Server Gateway Interface
WSGI is the Web Server Gateway Interface. It is a specification for web servers and application servers to communicate with web applications (though it can also be used for more than that)
WSGI是一种Web服务器网关接口,它是一个Web服务器(如nginx)与应用服务器(如uWSGI服务器)通信的一种规范。
从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。
WSGI 是作为 Web 服务器与 Web 应用程序或应用框架之间的一种低级别的接口,以提升可移植 Web 应用开发的共同点。WSGI 是基于现存的 CGI 标准而设计的。
很多框架都自带了 WSGI server ,比如 Flask,webpy,Django、CherryPy等等。当然性能都不好,自带的 web server 更多的是测试用途,发布时则使用生产环境的 WSGI server或者是联合 nginx 做 uwsgi 。
也就是说,WSGI就像是一座桥梁,一边连着web服务器,另一边连着用户的应用。但是呢,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进行处理。
WSGI 的作用如图所示:
WSGI的作用
WSGI有两方:“服务器”或“网关”一方,以及“应用程序”或“应用框架”一方。
服务方调用应用方,提供环境信息,以及一个回调函数(提供给应用程序用来将消息头传递给服务器方),并接收Web内容作为返回值。
所谓的 WSGI中间件同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用:从WSGI服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。
“中间件”组件可以执行以下功能:
- 重写环境变量后,根据目标URL,将请求消息路由到不同的应用对象。
- 允许在一个进程中同时运行多个应用程序或应用框架。
- 负载均衡和远程处理,通过在网络上转发请求和响应消息。
- 进行内容后处理,例如应用XSLT样式表。
WSGI 的设计确实参考了 Java 的 servlet。
Python Web Server Gateway Interface,有这么一段话:
By contrast, although Java has just as many web application frameworks available, Java's "servlet" API makes it possible for applications written with any Java web application framework to run in any web server that supports the servlet API.
uWSGI 协议
uWSGI是一个Web服务器,它实现了WSGI、uwsgi、http等协议。
Nginx中Http Uwsgi Module的作用是与uWSGI服务器进行交换。
要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
- WSGI,是一种Web服务器网关接口,一种通信协议。
- uwsgi,同WSGI一样,是一种通信协议。
- uWSGI,是实现了uwsgi和WSGI两种协议的Web服务器。
uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。
关于uwsgi协议看这里:The uwsgi protocol
为什么有了uWSGI还需要nginx?
因为nginx具备优秀的静态内容处理能力,然后将动态内容(如PHP,Python)转发给uWSGI服务器,这样可以达到很好的客户端动态响应。
uWSGI 安装
uWSGI 的安装很简单:
pip install uwsgi
示例:将 Django 实例跑起来
先在 virtualenv 创建一个 Django Project:
[root@nowamagic ~]# cd nowamagic_venv [root@nowamagic nowamagic_venv]# source bin/activate (nowamagic_venv) [root@nowamagic nowamagic_venv]# django-admin.py startproject nowamagic_pj
virtualenv 的路径与目录文件如下:
Django Project 的路径与目录文件如下:
测试 uwsgi
在你的服务器上写一个test.py:
# test.py def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return "Hello World"
我的 test.py 的路径是 /root/nowamagic_venv/nowamagic_pj/test.py,执行以下命令:
[root@nowamagic ~]# cd nowamagic_venv [root@nowamagic nowamagic_venv]# source bin/activate (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,显示 Hello World,说明 uwsgi 安装成功。
测试你的 Django 项目
前面我们用 django-admin.py startproject nowamagic_pj 创建了一个项目,现在我们用 Django 自带的 Web 服务器看看我们的项目有没出问题。还是进入我们虚拟环境:
[root@nowamagic ~]# cd nowamagic_venv [root@nowamagic nowamagic_venv]# source bin/activate (nowamagic_venv) [root@nowamagic nowamagic_venv]# python2.7 /root/nowamagic_venv/nowamagic_pj/manage.py runserver 0.0.0.0:8002
执行这个命令报错:No module named django.core.management,原因应该是装了多个版本的Python导致的。命令指定文件路径就行,丑是丑些了:
(nowamagic_venv) [root@nowamagic nowamagic_venv]# /usr/local/bin/python2.7 /root/nowamagic_venv/nowamagic_pj/manage.py runserver 0.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/ 下:
#!/usr/bin/env python # coding: utf-8 import os import sys # 将系统的编码设置为UTF8 reload(sys) sys.setdefaultencoding('utf8') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "nowamagic_pj.settings") from django.core.handlers.wsgi import WSGIHandler application = WSGIHandler()
OK,进入虚拟环境执行指令:
[root@nowamagic ~]# cd nowamagic_venv [root@nowamagic nowamagic_venv]# source bin/activate (nowamagic_venv) [root@nowamagic nowamagic_venv]# uwsgi --http :8000 --chdir /root/nowamagic_venv/nowamagic_pj/ --module django_wsgi
成功显示 Django It Works 页面。
这样,你就可以在浏览器中访问你的Django程序了。所有的请求都是经过uwsgi传递给Django程序的。
这里我们介绍了如何把uwsgi与Django连接起来,在下一篇将继续介绍如何将uwsgi与Nginx连接。
Nginx 配置
在 nginx.conf 上加入/修改, server 配置如下:
server {
listen 80;
server_name 115.28.0.89;
#server_name localhost;
access_log /home/nowamagic/logs/access.log;
error_log /home/nowamagic/logs/error.log;
#root /root/nowamagic_venv/nowamagic_pj;
location / {
uwsgi_pass 127.0.0.1:8077;
#include uwsgi_params;
include /etc/nginx/uwsgi_params;
#uwsgi_pass 127.0.0.1:8077;
#uwsgi_param UWSGI_SCRIPT index;
#uwsgi_param UWSGI_PYHOME $document_root;
#uwsgi_param UWSGI_CHDIR $document_root;
}
access_log off;
}
注意保证配置里写的目录 /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 目录下
<uwsgi> <socket>127.0.0.1:8077</socket> <listen>80</listen> <master>true</master> <pythonpath>/root/nowamagic_venv/nowamagic_pj</pythonpath> <processes>1</processes> <logdate>true</logdate> <daemonize>/var/log/uwsgi.log</daemonize> <plugins>python</plugins> </uwsgi>
然后执行命令:
uwsgi -x /root/nowamagic_venv/nowamagic_pj/nowamagic_pj.xml or /usr/local/bin/uwsgi -x /root/nowamagic_venv/nowamagic_pj/nowamagic_pj.xml
加载指定的xml配置文件。当使用命令行参数时,可以使用简化命令“-x”。当然也可以不简写:
uwsgi --xml /etc/nowamagic.xml
甚至如果在命令行的最后一个参数以“.xml”结尾,那么就隐含将加载该xml文件作为配置。
uwsgi /etc/nowamagic.xml
有时候因各种环境问题,-x --xml 命令识别不了,可以使用下面的 ini 配置方式:
2. ini 配置
[uwsgi] vhost = false plugins = python socket = 127.0.0.1:8077 master = true enable-threads = true workers = 1 wsgi-file = /root/nowamagic_venv/nowamagic_pj/nowamagic_pj/wsgi.py virtualenv = /root/nowamagic_venv chdir = /root/nowamagic_venv/nowamagic_pj
然后执行命令:
uwsgi --ini /root/nowamagic_venv/nowamagic_pj.ini&
uwsgi 这样就启动起来了。如果无意外的话,就能在网上访问你的 Python 项目了。
小插曲
我在配置完 Nginx 和 uWSGI 之后,访问时显示 502 错误。查看 uWSGI 启动信息,发现这么一条:ImportError: No module named django.core.wsgi。
然后推断,我的 CentOS 上的 Python 版本是 2.4.3,然后进入 virtualenv,执行:
python <<< import django <<< from django.core.wsgi import get_wsgi_application <<<
则没报错,因为我的虚拟环境里的 Python 版本是 2.7.5。推断成立,但是虚拟环境里的 Django 会默认调用外部环境的 Python。解决方法:在虚拟环境里 pip install django。
OK,问题解决,一切正常。
附
一些我在配置时用到的命令,省得你去搜索:
1. 关闭 uWSGI:
killall -9 uwsgi killall -s HUP /var/www/uwsgi killall -s HUP /usr/local/bin/uwsgi
2. 列出端口占用情况:
netstat -lpnt
参考推荐:
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2015-06-06 06:06:11
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!
转载注明: uWSGI 安装与应用 (米扑博客)
Python 语言最近好多人在学。。