前言
这几天又大致的复习了一下Django的相关内容,发现很多东西都忘得差不多了。看来知识的确是很容易就被遗忘的。时常按照艾宾浩斯记忆曲线来复习一下之前学过的,遗忘的速度就减慢许多了。
废话扯多了,今天主要是写点关于Django应用部署的笔记。毕竟今后一定会用得到,于是先给自己充点电,权当是准备一下。
总的来说有下面三种方式,接下来简答的描述一下。
- Apache+wsgi
- uWSGI
- Nginx+uWSGI
Apache+wsgi
Apache是家喻户晓的了。当然了,不是说阿帕奇武直多么厉害,而是这个服务器。而wsgi是什么意思咧?
wsgi全称 Web Server Gateway Interface。是专门为Python语言定义的Web服务器和Web应用程序或者框架之间的一种简单而通用的接口。
WSGI是Web服务器与Web应用之间的一种低级别的接口,我们可以理解为一个桥梁,通过这座桥梁实现了Web应用在Web服务器上的部署。
环境搭建
安装Apache
sudo apt-get -y install apache
安装mod_wsgi
sudo apt-get -y install libapache2-mod-wsgi
添加django.wsgi文件
这个django.wsgi文件的作用就是告诉Apache服务器,到底要怎么将Django应用程序和Apache服务器联系起来。
文件的内容如下:
#!/usr/bin/env python3
# coding: utf8
import os
import sys
# Django的项目的绝对目录
path = 'home/biao/guest/'
sys.path.append(path)
sys.path.append(path+'guest')
os.environ['DJANGO_SETTINGS_MODULE'] = 'guest.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
配置/etc/apache2/httpd.conf
……
#添加mod_wsgi.so 模块
LoadModule wsgi_module modules/mod_wsgi.so
#指定myweb项目的wsgi.py配置文件路径
WSGIScriptAlias / /home/biao/guest/django.wsgi
#指定项目路径
WSGIPythonPath /home/biao/guest
<Directory /home/biao/guest>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
wsgi.py配置
最后是修改guest应用下的wsgi.py文件。
……
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "guest.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
跑起来吧
然后重启一下Apache服务即可。
service apache2 reload
或者使用下面的命令
sudo /etc/init.d/apache2 restart
uWSGI
uWSGI 是一个Web服务器,它实现了WSGI, uwsgi,HTTP等协议(这里姑且把WSGI接口看作是一个协议吧)。 这一点要和uwsgi区别对待即可。
环境搭建
首先当然是得先安装这个服务器了。
pip install uWSGI
具体的版本可以在 https://pypi.python.org/pypi/uWSGI 处下载。
测试一下
安装完毕之后,我们先来测试一下uWSGI能否正常工作。根据其实现了uwsgi和WSGI协议,我们可以写出下面的桥接。
# coding: utf8
# file: test.py
# author: 郭璞
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')]
return [b'It Works.']
运行文件命令
uwsgi --http :8080 --wsgi-file test.py
部署Django应用
部署Django应用的命令很长,接下来一一讲解各个参数的含义。
uwsgi --http :8080 --chdir /home/biao/guest --wsgi-file guest/wsgi.py --master --processes 4
root@iZ2zeigvkok5ldc6x0m6itZ:/home/biao/guest# uwsgi --http :8080 --chdir /home/biao/guest --wsgi-file guest/wsgi.py --master --processes 4
*** Starting uWSGI 2.0.15 (64bit) on [Tue May 30 10:57:10 2017] ***
compiled with version: 4.8.4 on 29 May 2017 15:26:43
os: Linux-3.13.0-86-generic #130-Ubuntu SMP Mon Apr 18 18:27:15 UTC 2016
nodename: iZ2zeigvkok5ldc6x0m6itZ
machine: x86_64
clock source: unix
detected number of CPU cores: 1
current working directory: /home/biao/guest
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
chdir() to /home/biao/guest
your processes number limit is 7781
your memory page size is 4096 bytes
detected max file descriptor number: 65535
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :8080 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:41481 (port auto-assigned) fd 3
Python version: 3.4.3 (default, Nov 17 2016, 01:12:14) [GCC 4.8.4]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x25f0d10
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 363800 bytes (355 KB) for 4 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x25f0d10 pid: 16143 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 16143)
spawned uWSGI worker 1 (pid: 16145, cores: 1)
spawned uWSGI worker 2 (pid: 16146, cores: 1)
spawned uWSGI worker 3 (pid: 16147, cores: 1)
spawned uWSGI worker 4 (pid: 16148, cores: 1)
spawned uWSGI http 1 (pid: 16149)
参数释义
--http
: 协议类型和端口号 ,一般形式 –http :port--processes
: 开启的进程数量,对比上述的日志,我们可以看出有四个进程--chdir
: 指定项目的路径。--wsgi-file
: 指定wsgi文件的路径,这里是相对于chdir的路径而言的,所以可以更加清爽的写路径。--master
: 允许主进程存在,不写则不允许存在--threads
: 开启的线程数量。
其实还有很多参数,但是对于部署而言,很多东西都要根据具体的硬件配置不断的调试,调优,才能发挥出服务器最大的能力。
Nginx+uWSGI
Nginx近年来可谓是风生水起。目前而言,Nginx+uWSGI作为Django应用的部署方案已经是很普遍的了。通常让Nginx作为前台接收各种请求,然后转发给下方的uWSGI来具体的处理各种请求。以此来达到一个更高的响应效率。
环境搭建
刚才已经安装好了uWSGI,这里就安装一下Nginx好了。具体的安装方式有源码安装和直接使用包管理工具安装,这里为了方便,就简单的采用包管理工具安装好了。
sudo apt-get -y install nginx
然后为了防止出现端口冲突,可以修改一下Nginx的默认监听端口。
vim /etc/nginx/sites-avaiable/default
然后重启一下服务
sudo /etc/init.d/nginx restart
然后访问一下端口为8888的链接。
整合
整合Nginx和uWSGI与Django应用的时候,需要一些配置文件。`.
tree . -I *.pyc -L 4
目录结构如下
.
├── db.sqlite3
├── django_uwsgi.ini
├── django.wsgi
├── guest
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── sign
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ ├── 0001_initial.py
│ ├── __init__.py
│ └── __pycache__
├── models.py
├── __pycache__
├── templates
│ ├── event_manage.html
│ ├── guest_manage.html
│ ├── index.html
│ ├── login.html
│ └── sign_index.html
├── tests.py
├── urls.py
├── views_if.py
└── views.py
我们需要了解的就是Django和uWSGI的整合。uWSGI可以通过XML文件或者INI文件来读取相关的配置信息。所以我们可以在django_uwsgi.ini文件中有如下声明。
大致的含义其实和之前第二种方式使用命令行来运行是一致的。
可以通过命令
uwsgi --ini django_uwsgi.ini
如果没有报错信息,说明可以正常运行。也说明了现在后台部分已经完毕了。只需要**前台**Nginx做一下路由即可。
Nginx配置
现在需要修改一下Nginx的配置,让它为我们的Django应用服务。其实说白了还是对于uWSGI的路由请求的分配。
vim /etc/nginx/sites-avaiable/default
在文件的末尾加上如下内容。含义是让Nginx监听服务器的10010端口,然后将请求转发给后台的uWSGI服务器。并作出相应的处理。
运行
现在我们可以测试一下运行效果。也就是说:
- 先开启uWSGI服务器。
- 然后开启Nginx服务器。
- 访问Nginx对外暴露的端口,看看能不能获取uWSGI的服务。
uwsgi --ini django_uwsgi.ini
/etc/init.d/nginx restart
发现已经可以正确运行了。如此即可。
总结
最后来总结一下需要注意的地方。
Apache的方式不是很赞同,虽然稳定性很高,但是配置起来不是很容易而且各种依赖。
uWSGI单独运行的话,也还可以。就是略显单薄。
Nginx配合uWSGI 给我的感觉就是很沉稳了。后台部分可以挂载多个uWSGI。
但是需要知道的是整合uWSGI和Nginx的时候的那个ini文件。
如果想直接通过uWSGI服务器获取服务,这里的请求方式与端口配置为 http = :port
如果要想通过Nginx配合uWSGI的方式获取服务,这里的请求方式与端口配置为socket = :port
对外网而言,要想正确访问到我们的Django服务,还需要一项配置ALLOWED_HOSTS
在项目根目录的settings.py文件中,对下面一项做下配置即可。
ALLOWED_HOSTS = ['www.example.com', 'ip', '*']
还有就是在生产环境下,Django的DEBUG开关也需要关闭一下。这样给用户的用户体验也会好上不少,还能在一定程度上保证应用的安全性。设置方式如下。
在项目根目录的settings.py文件中,对下面一项做下配置即可。
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
感觉还是有很多东西要去学习呵。