• 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 -r
    2.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/profile
      export 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]# python
      Python 3.5.2 (default, Aug  2 2016, 11:35:06) 
      [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
      Type "help", "copyright", "credits" or "license" for more information.
      >>> exit()     #<----退出python
      
      PS:如果不建立新安装路径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 --version
      Python 3.5.2
      
      #查看安装路径(可以省略这步)
      [root@web01 ~]# python
      Python 3.5.2 (default, May 27 2017, 18:39:42) 
      [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
      Type "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 ~]# python
      Python 3.5.2 (default, May 27 2017, 18:39:42) 
      [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
      Type "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 uwsgi
    root      17970   1000  0 19:12 pts/0    00:00:00 uwsgi --http :8000 --wsgi-file test.py
    root      17972  17970  0 19:12 pts/0    00:00:00 uwsgi --http :8000 --wsgi-file test.py
    root      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.backup
    
    2、更换成国内源
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
    
    3、之后运行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

  • 相关阅读:
    如何利用azMan (Authorization Manager) 实现 rolebased的安全验证机制
    如何处理源dump文件的mscordacwks.dll文件与调试机上的版本不一致问题而无法使用extension cmd的问题
    UI thread client callback和UI thread WCF Service一起工作时死锁的形成原因及解决方法
    如何在 IIS 6.0 上配置托管的 Web 应用程序时使用 SPN(包括Network service ,domain acount, NLB, host header等各种情况)
    WCF中各种Transaction的分类及其相关参数的设置
    利用windbg调试class type,value type以及MethodTable等强化C#的基本概念
    如何自定义Attribute class并将其应用到相应的class
    谷歌浏览器F12调试页面学习
    上班族致富之道
    折半插入排序
  • 原文地址:https://www.cnblogs.com/skiler/p/6931678.html
Copyright © 2020-2023  润新知