如何在生产上部署Django?
Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式。
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性能和瓶颈)
- 高度可定制(内存大小限制,服务一定次数后重启等)
1.Uwsgi 安装使用
1.# Install the latest stable release:
2.pip install uwsgi
3.# ... or if you want to install the latest LTS (long term support) release,
4.pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz
基本测试
Create a file called test.py:
# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"] # python3
#return ["Hello World"] # python2
运行
uwsgi --http :8000 --wsgi-file test.py
用uwsgi 启动django
uwsgi --http :8000 --module mysite.wsgi
可以把参数写到配置文件里
mystery@mystery-ThinkPad-E550c:~/mysite$ uwsgi.ini
[uwsgi]
http = :9999
#the local unix socket file than commnuincate to Nginx
socket = 127.0.0.1:8001
# the base directory (full path)
chdir = /home/ubuntu/mysite
# Django's wsgi file
wsgi-file = mysite/wsgi.py
# maximum number of worker processes
processes = 2
#thread numbers startched in each worker process
threads = 2
#monitor uwsgi status
stats = 127.0.0.1:9191
# clear environment on exit
vacuum = true
在项目下启动
uwsgi uwsgi.ini
2.Nginx安装使用
sudo apt-get install nginxsudo /etc/init.d/nginx start # start nginx
为你的项目生成Nginx配置文件
You will need the uwsgi_params file, which is available in the nginx directory of the uWSGI distribution, or from https://github.com/nginx/nginx/blob/master/conf/uwsgi_params
Copy it into your project directory. In a moment we will tell nginx to refer to it.
Now create a file called mysite_nginx.conf, and put this in it:
#mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001;# for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name mysite.example.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /path/to/your/mysite/media; # your Django project's media files - amend as required
}
location /static {
alias /home/ubuntu/mysite/public; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/ubuntu/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
这个文件告诉nginx提供从文件系统介质和静态文件,以及处理请求,Django的干预。对于一个大的部署是很好的做法,让一个服务器处理静态/媒体文件,和另一个Django应用,但现在,这就好了。
Symlink to this file from /etc/nginx/sites-enabled so nginx can see it:
#建立软连接
sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
部署静态文件
Before running nginx, you have to collect all Django static files in the static folder. First of all you have to edit mysite/settings.py adding:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
And then run:
python manage.py collectstatic
此时启动Nginx 和Uwsgi,你的django项目就可以实现高并发啦!
3.supervistor进程监控
1.首先安装supervisor
sudo apt-get install supervisor
2.对默认配置文件备份
echo_supervisord_config > /etc/supervisor/supervisord.conf.default
配置文件如下:
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
3.修改 /etc/supervisor/supervisord.conf ,在最下面加入监控程序的配置
[program:project_name] # project_name这里写上你的项目名称,如我的为[project:mysite]
command = /home/ubuntu/.virtualenvs/python3/bin/uwsgi --ini /home/ubuntu/mysite/uwsgi.ini # 跟手动启动的命令一样(带虚拟环境)
stopsignal=QUIT
autostart=true
autorestart=true
stdout_logfile=/var/log/uwsgi/supervisor_chihu.log # 运行日志
stderr_logfile=/var/log/uwsgi/supervisor_chihu_err.log # 错误日志
4.启动supervisord
supervisorctl reload
提示错误
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 224
只需手动启动supervisord即可:
sudo supervisord -c /etc/supervisor/supervisord.conf
提示错误
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.
解决方式:
sudo unlink /tmp/supervisor.sock
sudo unlink /var/run/supervisor.sock# 重新手动启动
5.检查uwsgi进程是否正常运行
ps aux|grep uwsgi