直接使用uWSGI来运行Django
2017-07-06 10:35:19 +08 字数:1809 标签: uWSGI Django简介 ¶
Python应用提供Web服务,往往需要一种连接网关与应用的中间件。
通常使用WSGI规范来连接,而uWSGI则是一个实现这个规范的软件。
WSGI简介 ¶
网络服务器网关接口(Web Server Gateway Interface,缩写WSGI), 是为Python定义的一套简单而通用的规范, 用于连接网络服务器与网络应用或框架。
The Web Server Gateway Interface (WSGI) is a specification for simple and universal interface between web servers and web applications or frameworks for the Python programming language.
版本 | 文档 | 日期 |
---|---|---|
1.0 | PEP-333 | 2003-12-07 |
1.0.1 | PEP-3333 | 2010-09-26 |
uWSGI简介 ¶
uWSGI是一个Web应用服务器,与Nginx、Apache类似,只是没那么全能。 而且,在需要实现WSGI规范时, Nginx是通过ngx_http_uwsgi_module的uwsgi_pass与uwsgi_params来支持, 而Apache是通过mod_uwsgi和mod_proxy_uwsgi来支持。
uWSGI项目,开源托管于GitHub。 它主要由C语言构成,也包含C++、Python、Ruby、Java等语言的包装。
uWSGI目前(2017年7月),已经发展到了2.0.15版本。 除了主要支持Python以外,它还对Lua、Perl、Ruby、Erlang、PHP、Go、JVM等,提供了不同程度的支持。
uWSGI由unbit.com提供商业技术支持。 该公司还另外提供一个更强大的Unbit hosting platform,是uWSGI的强化版。
使用 ¶
在一个具备Python的环境下,用pip install uWSGI
就可安装。
在Docker中会麻烦一些,详见孤之前写的《在Docker中安装uWSGI》。
uWSGI的简单使用 ¶
把以下内容,写入hello_wsgi.py
文件。
这就是一个简单的Hello World网络应用了。
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
用uwsgi
命令,在8000端口运行。
然后可以在浏览器中,看到返回结果。
$ uwsgi --http :8000 --wsgi-file hello_wsgi.py
Django生成的wsgi.py ¶
在目前最新的1.11版本中,通过Django的startproject
命令,可以生成一个wsgi.py
。
$ django-admin startproject mytest
$ tree mytest/
mytest/
├── manage.py
└── mytest
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
进入mytest
目录,运行./manage.py runserver
,即可在8000端口看到新生成的项目首页。
runserver
是调试用的。
正式使用时,可以指定wsgi.py
文件给uWSGI。
$ uwsgi --http :8000 --wsgi-file mytest/wsgi.py
wsgi.py的内容 ¶
Django自动生成的wsgi.py
文件短小精干:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mytest.settings")
application = get_wsgi_application()
而打开django.core.wsgi
模块,可以看到get_wsgi_application
函数,只是一次简单的转交。
import django
from django.core.handlers.wsgi import WSGIHandler
def get_wsgi_application():
"""
The public interface to Django's WSGI support. Should return a WSGI
callable.
Allows us to avoid making django.core.handlers.WSGIHandler public API, in
case the internal WSGI implementation changes or moves in the future.
"""
django.setup(set_prefix=False)
return WSGIHandler()
在django.core.handlers.wsgi
模块,WSGIHandler
的代码如下:
class WSGIHandler(base.BaseHandler):
request_class = WSGIRequest
def __init__(self, *args, **kwargs):
super(WSGIHandler, self).__init__(*args, **kwargs)
self.load_middleware()
def __call__(self, environ, start_response):
set_script_prefix(get_script_name(environ))
signals.request_started.send(sender=self.__class__, environ=environ)
request = self.request_class(environ)
response = self.get_response(request)
response._handler_class = self.__class__
status = '%d %s' % (response.status_code, response.reason_phrase)
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
start_response(force_str(status), response_headers)
if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'):
response = environ['wsgi.file_wrapper'](response.file_to_stream)
return response
可见,WSGIHandler
与之前的hello_wsgi.py
,形式上也差不多。
这就是实现WSGI的关键内容。
在没有自动生成wsgi.py
的Django老版本,可以通过上述内容,自己写一个。
uWSGI配置 ¶
uwsgi
命令的参数太多了。
在当前版本下,光帮助文档就有近千行。
$ uwsgi -h | wc
997 8772 92257
使用wsgi.py的配置 ¶
在复杂情况下,利用配置文件,是更好的选择。
例如,前面的uwsgi --http :8000 --wsgi-file mytest/wsgi.py
,
可以写成如下形式的mytest.ini
文件。
[uwsgi]
http = :8000
wsgi-file = mytest/wsgi.py
然后,通过uwsgi mytest.ini
,即可执行。
不使用wsgi.py的配置 ¶
wsgi.py
不是必须的。
[uwsgi]
http = :8000
env = DJANGO_SETTINGS_MODULE=mytest.settings
module = django.core.wsgi:get_wsgi_application()
这一配置,相当于重写了wsgi.py
文件的内容。
Django 1.4以前的配置 ¶
对Django 1.4以前的版本,不会自动生成wsgi.py
文件,也没有get_wsgi_application
函数。
可以使用以下配置去替代。
[uwsgi]
http = :8000
env = DJANGO_SETTINGS_MODULE=mytest.settings
module = django.core.handlers.wsgi:WSGIHandler()
注意:这一写法在1.4及以上版本无效,因为那以后的Django需要初始化。
错误提示:
django.core.exceptions.AppRegistryNotReady: Apps aren’t loaded yet.
其它配置 ¶
上面展示的是必须的最简配置。 除此之外,以下配置也较为常见。
[uwsgi]
chdir = /PATH/TO/YOUR/PROJECT
master = true
processes = 4
threads = 2
stats = 127.0.0.1:9191
static-map = /static=/PATH/TO/DJANGO/STATIC
以上配置的具体含义,以及其它更多的配置,可以查看uwsgi -h
,
或者官方文档《uWSGI Options — uWSGI》