Django + uWSGI + Nginx 实现django项目在生产环境部署
uwsgi介绍
uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
- WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。
- uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。
- 而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
- uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。
uWSGI的主要特点如下
- 超快的性能
- 低内存占用(实测为apache2的mod_wsgi的一半左右)
- 多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
- 详尽的日志功能(可以用来分析app性能和瓶颈)
- 高度可定制(内存大小限制,服务一定次数后重启等)
uWSGI 安装及使用
安装uwsgi服务
pip3 install uwsgi
运行一个简单的uwsgi服务
#先创建一个test.py模块如下:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"test a uwsgi server...."] # python3
#return ["test a uwsgi server...."] # python2
#基于这个测试的test.py模块启动一个简单的uwsgi服务
uwsgi --http :8000 --wsgi-file test.py
#通过浏览器输入172.16.1.121:8000显示结果为:test a uwsgi server....
用uwsgi启动一个django项目,比如启动一个完整的PerfectCRM项目
#先将PerfectCRM项目拷贝到部署uwsgi服务的设备上
#解压
unzip PerfectCRM.zip
#进入PerfectCRM项目目录
cd PerfectCRM
# PerfectCRM目录结构如下:
[root@goser2 PerfectCRM]# ls
?-+? db.sqlite3 manage.py statics uwsgi.ini
dd PerfectCRM student crm kingadmin templates
#这里用到sqlite数据库服务,所以要安装sqllite服务,但生产上不需要,因为生产上基本用mysql数据库
yum install sqlite-devel -y
#安装好sqlite数据库后,要重新编译python3
cd python3.5
./configure
make && make install
#用uwsgi启动django项目的服务
uwsgi --http :8080 --module PerfectCRM.wsgi --static-map=/static=statics
参数说明:
--http 这个就和runserver一样指定IP 端口
-- static 做一个映射,指定django项目下静态文件所在的文件夹
-- module 指定uwsgi服务要启动django项目下的wsgi.py模块
使用浏览器连接PerfectCRM服务如下:

但当进入admin视图的时候出现加载不了静态文件,如下:

admin视图的静态文件加载不了,说明uwsgi服务启动的时候,指定的静态文件不包含admin的静态文件,解决办法如下:
#在django项目的settings.py文件中配置static_root指定静态文件存放的位置 #这个位置是django项目下所有静态文件的位置(当然包括admin的静态文件) STATIC_ROOT = 'all_static_files' #然后执行下面命令,让所有的静态文件拷贝到指定的文件夹中 python3 manage.py collectstatic
这时候在django项目下就会生成指定存放静态文件的文件夹all_static_files,最后重新启动django项目的uwsgi服务并指定静态映射的文件夹为all_static_files
#在项目中生成all-static_files文件夹 [root@goser2 PerfectCRM]# ls ?-+? db.sqlite3 manage.py statics uwsgi.ini all_static_files dd PerfectCRM student uwsgi_params crm kingadmin templates #重新启动django的uwsgi服务 uwsgi --http :8080 --module PerfectCRM.wsgi --static-map=/static=all_static_files
最后再进入admin视图就正常了,admin视图需要的静态文件加载成功

使用uwsgi配置文件启动django项目
进入django项目,在项目下创建script目录,用于存放配置脚本等等
[root@goser2 ~]# cd PerfectCRM [root@goser2 PerfectCRM]# mkdir script
进入/script目录,创建一个uwsgi.ini文件如下
[root@goser2 PerfectCRM]# cd script/ [root@goser2 script]# cat uwsgi.ini [uwsgi] # 项目目录 chdir=/root/PerfectCRM/ # 指定项目的application module=PerfectCRM.wsgi:application # 指定sock的文件路径 socket= :8001 # 进程个数 workers=5 pidfile=/root/PerfectCRM/script/uwsgi.pid # 指定IP端口 http= :8080 # 指定静态文件 static-map=/static=/root/PerfectCRM/all_static_files # 启动uwsgi的用户名和用户组 uid=root gid=root # 启用主进程 master=true # 自动移除unix Socket和pid文件当服务停止的时候 vacuum=true # 序列化接受的内容,如果可能的话 thunder-lock=true # 启用线程 enable-threads=true # 设置自中断时间 harakiri=30 # 设置缓冲 post-buffering=4096 #监控uwsgi服务指定的端口 stats = :9191 # 设置日志目录 daemonize=/root/PerfectCRM/script/uwsgi.log
基于配置文件uwsgi.ini启动项目的uwsgi服务,并用连接uwsgi服务来验证是否正常
[root@goser2 script]# uwsgi --ini uwsgi.ini [uWSGI] getting INI configuration from uwsgi.ini [uwsgi-static] added mapping for /static => /root/PerfectCRM/all_static_files

至此,uwsgi+django就完美结合了,但是,生产环境中常用的还是uwsgi+django+nginx来启动一个django应用。
Django + uWSGI + Nginx 实现django项目在生产环境部署
这里部署的nginx服务主要用于后端uwsgi+django反向代理,当前端用户访问django app服务时候,通过nginx的反向代理,将用户的请求转发到后端的uwsgi服务上,当uwsgi服务处理完转发来的请求将结果返回给nginx服务,最后由nginx反向代理服务将结果再返回给客户端用户,架构流程图如下:

首先部署nginx服务,提供后端uwsgi服务的反向代理
yum install pcre pcre-devel openssl openssl-devel -y
useradd nginx -s /sbin/nologin -M
wget -q http://nginx.org/download/nginx-1.6.3.tar.gz
tar xf nginx-1.6.3.tar.gz
cd nginx-1.6.3
mkdir /application
./configure --prefix=/application/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module
make && make install
ln -s /application/nginx-1.6.3 /application/nginx
#修改nginx配置文件,让nginx服务可以反向代理到后端uwsgi服务
#注意要在配置文件中的server标签中添加uwsgi_params文件
cd /application/nginx
vim conf/nginx.conf
#配置上游服务器地址
upstream django {
server 172.16.1.121:8001; # for a web port socket (we'll use this first)
}
#配置一个server,作为前端访问uwsgi服务的入口
server {
listen 8000;
server_name crm.goser.com;
charset utf-8;
client_max_body_size 75M;
location / {
uwsgi_pass django;
include uwsgi_params; # the uwsgi_params file you installed
}
}
#检查配置文件语法,启动nginx服务
[root@goser1 ~]# /application/nginx/sbin/nginx -t
[root@goser1 ~]# /application/nginx/sbin/nginx
最后修改django项目下settings.py文件的ALLOWED_HOSTS 为ALLOWED_HOSTS = ["*"],然后前端访问nginx反向代理的8000端口来访问后端的uwsgi服务如下:

最后别忘了要关闭django项目的debug模式,这样在用户访问错误的页面的时候就不会出现报错的具体信息,保护了站点安全性
#生产上在settings.py中将debug模式取消:DEBUG = False [root@goser2 PerfectCRM]# vim PerfectCRM/settings.py # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False ALLOWED_HOSTS = ["*"] STATIC_ROOT = 'all_static_files'
浙公网安备 33010602011771号