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

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

一、Uwsgi 是啥?

WSGI(Web Server Gateway Interface),是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。

uWSGI 是一个快速的、纯C语言开发的、自维护的、对开发者友好的 WSGI 服务器,旨在提供专业的 Python web应用发布和开发。可使用 C/C++/Objective-C 来为 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的主要特点如下

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

二、Nginx是啥?

Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。其特点是占有内存少,并发能力强。

三、比较好使的框架结构

技术分享

技术分享

 

 

 四、环境搭建

a、Linux服务器一台

技术分享
[root@web01 ~]# cat /etc/redhat-release CentOS release 6.6 (Final)[root@web01 ~]# uname -r2.6.32-504.el6.x86_64
系统和内核版本

b、安装Python和Django相关的软件和工具包

  1. 安装setuptools
    技术分享
    [root@django tools]# yum install pcre pcre-devel openssl openssl-devel zlib bzip2-devel -y[root@django tools]# ll -rw-r--r-- 1 root root 641502 3月   2 18:50 setuptools-19.6.tar.gz[root@django tools]# tar xf setuptools-19.6[root@django tools]# cd setuptools-19.6[root@django tools]#python setup.py install[root@django tools]#cd ..###################################################################nginx模块pcre pcre-devel  #perl语言兼容正则表达式,用来做Nginx的HTTP Rewrite 模块bzip2-devel   ·#提供压缩功能openssl openssl-devel  #https加密模块###################################################################zlib #在编译python3的时候,加载setuptools的时候会报错,所以这里提前处理啦!
    源码安装setuptools
  2. 安装pip
    技术分享
    [root@django tools]# ll -rw-r--r-- 1 root root 1197370 3月   2 13:30 pip-9.0.1.tar.gz[root@django tools]# tar xf pip-9.0.1.tar.gz [root@django tools]# cd pip-9.0.1[root@django pip-9.0.1]# python setup.py install[root@django pip-9.0.1]# cd ..#配置环境变量:[root@django bin]# vi /etc/profileexport PATH="/usr/local/python3/bin:$PATH"  [root@django bin]# tail -1 /etc/profile  export PATH="/usr/local/python3/bin:$PATH"  [root@django bin]# source /etc/profile  #查看帮助  [root@django bin]# pip3  或 pip
    升级到最新的pip
  3. 安装sqlite3
    技术分享
    方法一:yum install sqlite-devel或方法二:软件下载官网:http://www.sqlite.org[root@django tools]# ll-rw-r--r-- 1 root root 2515143 3月   2 13:33 sqlite-autoconf-3170000.tar.gz[root@django tools]# tar xf sqlite-autoconf-3170000.tar.gz[root@django tools]# cd sqlite-autoconf-3170000[root@django tools]# ./configure[root@django tools]#make && make install
    安装sqlite
  4. 升级到Python3
    技术分享
    方法一:升级为python3.5版本步骤root@template ~]# cd /home/oldboy/tools/#下载python-3.5.2[root@template tools]# wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz[root@template tools]# ll总用量 20104-rw-r--r--  1 root root 20566643 6月  26 05:47 Python-3.5.2.tgz#解压到下载目录[root@template tools]# tar zxvf Python-3.5.2.tgz #进入解压后的文件夹[root@template tools]# cd Python-3.5.2#在编译前先在/usr/local建一个文件夹python3(作为python的安装路径,以免覆盖老的版本)[root@template Python-3.5.2]# mkdir /usr/local/python3#开始编译安装[root@template Python-3.5.2]#  ./configure --prefix=/usr/local/python3[root@template Python-3.5.2]# make && make install此时没有覆盖老版本,再将原来/usr/bin/python链接改为别的名字[root@template Python-3.5.2]# mv /usr/bin/python /usr/bin/python_old#再建立新版本python的软链接[root@template Python-3.5.2]# ln -s /usr/local/python3/bin/python3 /usr/bin/python#就会显示出python的新版本信息[root@template Python-3.5.2]# pythonPython 3.5.2 (default, Aug  2 2016, 11:35:06) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linuxType "help", "copyright", "credits" or "license" for more information.>>> exit()     #<----退出pythonPS:如果不建立新安装路径python3,而是直接默认安装,则安装后的新python应该会覆盖linux下自带的老版本。当然如果还想保留原来的版本,那么这种方法最好不过了。注意事项:这种方法虽然能安装成功,但会导致yum不能正常使用。解决方法:[root@template tools]# cp /usr/bin/yum /usr/bin/yum.backup_2016-08-02修改第一行参数vi /usr/bin/yum   把  #!/usr/bin/python    修改为:/usr/bin/python_old  或把  #!/usr/bin/python    修改为:/usr/bin/python2.6#查看版本[root@template Python-3.5.2]# python --versionPython 3.5.2#查看安装路径(可以省略这步)[root@web01 ~]# pythonPython 3.5.2 (default, May 27 2017, 18:39:42) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import sys>>> print(sys.path)[‘‘, /usr/local/python3/lib/python35.zip, /usr/local/python3/lib/python3.5, /usr/local/python3/lib/python3.5/plat-linux, /usr/local/python3/lib/python3.5/lib-dynload, /usr/local/python3/lib/python3.5/site-packages]>>> exit()
    安装python3
  5. 安装Django
    技术分享
    方式一:用pip3安装pip3 install django升级方法:pip3 install django --upgrade
    安装Django包
  6. 安装PyMysql (选装,具体看项目使用的数据库)
    技术分享
    pip3 install PyMySQL#检查模块是否安装成功[root@web01 ~]# pythonPython 3.5.2 (default, May 27 2017, 18:39:42) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import pymysql >>> >>> exit()
    安装pyMysql模块

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# 启动[root@web01 uwsgi_test]# uwsgi --http :8000 --wsgi-file test.py# 查看进程[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的测试

 

d、nginx的安装

  1.  更改操作系统默认的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生成缓存

  2. 安装nginx

yum -y install nginx

 

六、启动项目

 a、uWSGI的启动

  1.   命令行启动
    [root@python-dev ~]# uwsgi --http 192.168.14.4:8080 --file teacher/wsgi.py --static-map=/static=static

     

  2. 配置文件启动
    技术分享
    # 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
    配置文件样例
    技术分享
    # 通过配置文件启动        uwsgi --ini uwsgi.ini        # 会生成两个文件            PID文件 他是标识这个程序所处的状态            SOCK文件  他是用来和其他程序通信的    # 停止uwsgi        uwsgi --stop uwsgi.pid    # 重载配置        uwsgi --reload uwsgi.ini
    配置文件启动命令

     

b、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的配置
技术分享
/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 
nginx命令

解决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/;
静态文件bug

参数优化,请参考官方文档:

首先参考下官网的 things to know : http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html

     我这边最终启动的命令如下: 

     uwsgi --socket 127.0.0.1:9090 -p 16 -l 8192 -M -R 100000  -z30 -L --wsgi-file  app.py --max-apps 65535 --stats 127.0.0.1:1717 --post-buffering 100M --cpu affinity --buffer-size 65535 --daemonize /tmp/uwsgi --pidfile /tmp/uwsgi.pid  --memory-report --threads 16

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