首页 > 代码库 > 利用Django构建web应用及其部署
利用Django构建web应用及其部署
注:很久之前就有了学习Django的想法,最近终于有机会做了一次尝试。由于Django的详细教程很多,我在这里就不再详述了,只是将整个开发流程以及自己在学习Django中的一些思考记录在此。
System:CentOS Linux release 7.2.1511 (Core)
Django: 1.10
Python: 2.7.5
推荐两个非常好的教程:
The Django Book(中文版):我自己一开始是参考这个教程学习的,非常有意思的是这个教程中有大量的评论,几乎每段都有,从10年开始一直到现在。虽然这本书比较老,有很多内容都过时了,但在这些评论中有讲解,有勘误和最新的实践,这些评论让整个学习过程变得非常有趣。我自己也留下了不少评论,哈哈。
被解放的姜戈:这是博客园的另一位博友Vamei(中文读作,挖煤)写的关于Django简介的系列文章,基本概念,简单的实践都有。
不是要点的要点
- 创建一个专门的用户,例如www-data:在后面部署Django的过程中,我遇到了自使用Linux以来,最多的权限问题。很大的原因是因为不同进程间需要通信,或相互访问,这就需要这些用户间都有某个文件的读写权限。例如两个进程都要访问同一个socket文件时,这两个进程的用户都要对该socket文件有读写权限。因此将所有这些进程都交给一个专门的用户来操作,可以避免很多权限问题。
- url是web开发的核心要素之一:在客户端,每一个url就是一个页面;从开发者来看,所有的开发都是围绕如何正确的路由这些url到正确的html文件来展开的。
- stackoverflow是一个很棒的网站,大部分的问题都可以在上面找到解决方案,如果没有找到答案,就提问吧,很快就可以得到回复。
概述
用户从浏览器访问一个django开发的页面,整个流程是这样的:
the web client <-> the web server <-> the socket <-> WSGI <-> Django
用户从浏览器访问一个url,该请求从用户发送到web server,web server通过socket(或者约定一个端口)与WSGI进行通信,再由WSGI将请求发给django。web server和WSGI都有很多种选择,常见的组合有Apache + mod_wsgi和nginx + uWSGI。我用的是nginx + uWSGI。下面先介绍几个名词。
web server:
虽然每个网页服务器程序有很多不同,但有一些共同的特点:每一个网页服务器程序都需要从网络接受HTTP请求,然后提供HTTP回复给请求者。HTTP回复一般包含一个HTML文件,有时也可以包含纯文本文件、图像或其他类型的文件。
一般来说这些文件都存储在网页服务器的本地文件系统里,而URL和本地文件名都有一个阶级组织结构的,服务器会简单的把URL对照到本地文件系统中。当正确安装和设置好网页服务器软件,服务器管理员会从服务器软件放置文件的地方指定一个本地路径名为根目录。
web server是面对用户请求的第一道门,有些请求由web server自己处理,例如静态文件的访问等;还有一些请求则交给WSGI处理,如对动态页面的访问。
socket: 最近在学习《计算机网络》这门课,socket相关的内容在网络模型中属于传输层,位于网络层和应用层之间。主要用于实现进程间通讯。在这里主要是实现nginx和uWSGI两个不同进程之间的通讯。
WSGI:
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。
可以将WSGI看做是一种协议,据说之所以Python中有很多web框架,就是因为WSGI调用非常方便。uWSGI是WSGI这一协议的实现。在实际使用过程中,uWSGI代替了python manage.py runserver的作用,当然还有其他作用。
最早的Web服务器只支持静态html。随着网站也越来越复杂,出现了动态技术。但是服务器并不能直接运行 php,asp这样的文件,因此需要一个第三方,与第三方做个约定,我把请求参数发送给你,然后我接收你的处理结果给客户端。这个约定就是 common gateway interface,简称cgi。这个协议可以用vb,c,php,python 来实现。
简单地说,cgi是Web App与Http Server之间的桥梁。
除了cgi,还有wsgi(Web Service Gateway Interface)。WSGI所在层的位置低于CGI,与CGI不同的是WSGI具有很强的伸缩性且能运行于多线程或多进程的环境下,这是因为WSGI只是一份标准并没有定义如何去实现。实际上WSGI并非CGI,因为其位于web应用程序与web服务器之间,而web服务器可以是CGI。
所有均开始于settings文件
ROOT_URLCONF = ‘mysite.urls‘
# urls.pyfrom django.conf.urls import url, includefrom django.contrib import adminfrom mysite.views import helloadmin.autodiscover()urlpatterns = [ url(r‘^hello/$‘, hello),]
# viwes.pyfrom django.http import HttpResponsedef hello(request): return HttpResponse("Hello World!")
uWSGI与Django之间的通讯
uWSGI与Django之间的通讯是通过wsgi.py文件实现的,这个文件在创建Django project后就生成了。这里的设置中最主要的一点就是正确的指出settings.py文件的位置。因为Django中的一切都始于这个文件。可以先将project的主目录/home/www-data/djcode/mysite/添加到当前模块扫描的路径,这样就可以从该路径来导入其他文件了。
@ wsgi.py
"""WSGI config for helloworld project.It exposes the WSGI callable as a module-level variable named ``application``.For more information on this file, seehttps://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/"""import os, sys# Calculate the path based on the location of the WSGI script.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 如果wsgi.py文件位于/home/www-data/djcode/mysite/mysite/,则此时BASE_DIR为/home/www-data/djcode/mysite/
sys.path.append(BASE_DIR) # temple
# Add the path to 3rd party django application and to django itself.
from django.core.wsgi import get_wsgi_application
os.environ[‘DJANGO_SETTINGS_MODULE‘] = ‘mysite.settings‘ # 相当于从BASE_DIR导入mysite/settings.py文件
application = get_wsgi_application()
nginx的配置
由于一开始不熟悉,因此nginx的配置花了很长时间。其中的关键点是:不同的server之间是无法共用端口号(port)的,因此如果要使用同一个端口号,例如80端口,那么所有的路由都有配置在一个server中。
nginx的配置文件,可以参考这里nginx.conf
其他
进程管理:进程管理的工具也有很多,uWSGI中的Emperor mode与进程管理工具具有相似的功能,两者似乎无法共用。我选择的是Supervisor。
参考:
https://zh.wikipedia.org/wiki/%E7%B6%B2%E9%A0%81%E4%BC%BA%E6%9C%8D%E5%99%A8
https://zh.wikipedia.org/wiki/Berkeley%E5%A5%97%E6%8E%A5%E5%AD%97
https://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BD%91%E5%85%B3%E6%8E%A5%E5%8F%A3
http://djangobook.py3k.cn/2.0/
http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
https://www.quora.com/What-are-the-differences-between-nginx-and-gunicorn # 这里讲了为什么要使用nginx和gunicorn(作用同uWSGI)
http://data-eater.com/python-worker/
http://www.shellwjl.com/2016/03/07/ali_flask_wsgi_Nginx/
利用Django构建web应用及其部署