首页 > 代码库 > Django + Uwsgi + Nginx 实现生产环境部署

Django + Uwsgi + Nginx 实现生产环境部署

一、如何在生产上部署Django?

Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比较常见的一种方式。

二、uwsgi介绍

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。

  1. WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。
  2. uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。
  3. 而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
  4. uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

uwsgi性能非常高

技术分享

 

 

uWSGI的主要特点如下

  1. 超快的性能
  2. 低内存占用(实测为apache2的mod_wsgi的一半左右)
  3. 多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
  4. 详尽的日志功能(可以用来分析app性能和瓶颈)
  5. 高度可定制(内存大小限制,服务一定次数后重启等)

If you are searching for a simple wsgi-only server, uWSGI is not for you, but if you are building a real (production-ready) app that need to be rock-solid, fast and easy to distribute/optimize for various load-average, you will pathetically and morbidly fall in love (we hope) with uWSGI.

 

三、Django + Uwsgi + Nginx 生产部署

1、准备环境

a、需要linux服务器一台

b、在服务器上面安装好Python和Django

这里安装方法省略。。。。(不懂可以百度解决)

c、uwsgi

# 安装 uwsgi[root@localhost teacher]# pip3 install uwsgi

测试uwsgi

[root@web01 nulige]# cd /home/nulige[root@web01 nulige]# mkdir -p uwsgi_test[root@web01 nulige]# cd uwsgi_test/
#测试文件
[root@web01 uwsgi_test]# vi 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

[root@web01 uwsgi_test]# uwsgi --http :8000 --wsgi-file test.py*** Starting uWSGI 2.0.15 (64bit) on [Sat May 27 19:12:58 2017] ***compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-11) on 27 May 2017 18:48:50os: Linux-2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 04:27:16 UTC 2014nodename: web01machine: x86_64clock source: unixpcre jit disableddetected number of CPU cores: 1current working directory: /home/nulige/uwsgi_testdetected binary path: /usr/local/python3/bin/uwsgiuWSGI running as root, you can use --uid/--gid/--chroot options*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** *** WARNING: you are running uWSGI without its master process manager ***your processes number limit is 14719your memory page size is 4096 bytesdetected max file descriptor number: 1024lock engine: pthread robust mutexesthunder lock: disabled (you can enable it with --thunder-lock)uWSGI http bound on :8000 fd 4spawned uWSGI http 1 (pid: 17972)uwsgi socket 0 bound to TCP address 127.0.0.1:38831 (port auto-assigned) fd 3Python version: 3.5.2 (default, May 27 2017, 18:39:42)  [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)]*** Python threads support is disabled. You can enable it with --enable-threads ***Python main interpreter initialized at 0x1ed4a90your server socket listen backlog is limited to 100 connectionsyour mercy for graceful operations on workers is 60 secondsmapped 72768 bytes (71 KB) for 1 cores*** Operational MODE: single process ***WSGI app 0 (mountpoint=‘‘) ready in 0 seconds on interpreter 0x1ed4a90 pid: 17970 (default app)*** uWSGI is running in multiple interpreter mode ***spawned uWSGI worker 1 (and the only) (pid: 17970, cores: 1)

查看启动端口

[root@web01 ~]# ps -ef|grep uwsgiroot      17970   1000  0 19:12 pts/0    00:00:00 uwsgi --http :8000 --wsgi-file test.pyroot      17972  17970  0 19:12 pts/0    00:00:00 uwsgi --http :8000 --wsgi-file test.pyroot      17996  17973  0 19:14 pts/1    00:00:00 grep uwsgi

 

根据项目进行配置

# 启动 uwsgi    **进入项目目录**    **使用uwsgi启动前确保无代码问题导致通过runserver可以正常启动起来**    uwsgi --http 192.168.31.123:8080 --file teacher/wsgi.py --static-map=/static=static #测试启动    # 解释        --http 这个就和runserver一样指定IP 端口        --file 这个文件就里有一个反射,如果你在调用他的时候没有指定Web Server就使用默认的        -- static   做一个映射,指定静态文件

 

2、生产环境配置

Nginx + uWSGI + Djangos配置方法:

# uwsig使用配置文件启动    [uwsgi]    # 项目目录    chdir=/opt/project_teacher/teacher/    # 指定项目的application    module=teacher.wsgi:application    # 指定sock的文件路径    socket=/opt/project_teacher/script/uwsgi.sock    # 进程个数    workers=5    pidfile=/opt/project_teacher/script/uwsgi.pid    # 指定IP端口    http=192.168.31.123:8080    # 指定静态文件    static-map=/static=/opt/test_project/teacher/static    # 启动uwsgi的用户名和用户组    uid=root    gid=root    # 启用主进程    master=true    # 自动移除unix Socket和pid文件当服务停止的时候    vacuum=true    # 序列化接受的内容,如果可能的话    thunder-lock=true    # 启用线程    enable-threads=true    # 设置自中断时间    harakiri=30    # 设置缓冲    post-buffering=4096    # 设置日志目录    daemonize=/opt/project_teacher/script/uwsgi.log

# uwsig常用命令

    # 通过配置文件启动        uwsgi --ini uwsgi.ini        # 会生成两个文件            PID文件 他是标识这个程序所处的状态            SOCK文件  他是用来和其他程序通信的    # 停止uwsgi        uwsgi --stop uwsgi.pid    # 重载配置        uwsgi --reload uwsgi.ini

d、nginx

#先换成国内yum源

#以CentOS6.x 系统为例1、备份mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup2、更换成国内源wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo3、之后运行yum makecache生成缓存

# 安装nginx

yum -y install nginx

# Nginx添加配置文件

#先进入到配置文件:
vi /etc/nginx/conf.d/#编辑配置文件server { # 这个server标识我要配置了 listen 80; # 我要监听那个端口 server_name 10.129.205.183 ; # 你访问的路径前面的url名称 access_log /var/log/nginx/access.log main; # Nginx日志配置 charset utf-8; # Nginx编码 gzip on; # 启用压缩,这个的作用就是给用户一个网页,比如3M压缩后1M这样传输速度就会提高很多 gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream; # 支持压缩的类型 error_page 404 /404.html; # 错误页面 error_page 500 502 503 504 /50x.html; # 错误页面 # 指定项目路径uwsgi location / { # 这个location就和咱们Django的url(r‘^admin/‘, admin.site.urls), include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的 uwsgi_connect_timeout 30; # 设置连接uWSGI超时时间 uwsgi_pass unix:/opt/project_teacher/script/uwsgi.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给他 } # 指定静态文件路径 location /static/ { alias /opt/project_teacher/teacher/static/; index index.html index.htm; } }

# 启动Nginx通过Nginx访问

/etc/init.d/nginx start/etc/init.d/nginx stop# 这里有个命令configtest,Nginx配置是重启生效的,如果你修改完了,不知道对不对又担心影响其他人可以使用它测试/etc/init.d/nginx configtest# 如果是生产环境的话Nginx正在运行,就不要直接stop start 或者 restart  直接reload就行了# 对线上影响最低(生产环境用的方法)/etc/init.d/nginx reload 

e、Django Admin静态文件配置

有一个小bug: 

 

# 解决Django静态配置文件丢失

问题原因:    是因为admin所需的js,css等静态文件都在django的安装目录内,但是我们并没有配置指向Django的配置文件。解决办法:    我们可以通过配置 STATIC_ROOT = os.path.join(BASE_DIR, "static_all")来指定静态文件的默认家目录是那里,然后把项目里所有的静态文件都收集起来放到这个目录下面。收集命令:    python3 manage.py collectstatic --noinput修改Nginx 指定静态路径    alias  /opt/test_project/teacher/static_all/;

 

Django + Uwsgi + Nginx 实现生产环境部署