zoukankan      html  css  js  c++  java
  • uwsgi+nginx部署django项目

    1. 概念解析(wsgi协议,uwsgi协议,uWSGI)

      参考:https://www.cnblogs.com/wspblog/p/8575101.html 

          1.1 现实世界的web请求:

      1.2  wsgi协议,uwsgi协议和uWSGI

         a. WSGI(wsgi): 全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。

        总结:WSGI(wsgi)只是一种规范,描述web server如何与web application通信的规范

        b. uWSGI: uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。

        c. uwsgi: 与WSGI一样是一种通信协议,但与WSGI协议是两种东西,uwsgi协议是uWSGI服务器的独占协议,用于定义传输信息的类型(type of                                    information),每一个uwsgi packet前4byte为传输信息类型的描述.

        下图简单描述在web请求过程中三者的位置: 

    2. web请求流程

      1,首先客户端请求服务资源,

         2,nginx作为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析,如果是静态文件请求就根据nginx配置的静态文件目录,返回请求的资      源,如果是动态的请求,nginx就通过配置文件,将请求传递给uWSGI;

      3,uWSGI 将接收到的包进行处理,并转发给wsgi, wsgi根据请求调用django工程的某个文件或函数,处理完后django将返回值交给wsgi,wsgi将返回值进行打包,转发给uWSGI, uWSGI接收后转发给nginx,nginx最终将返回值返回给客户端(如浏览器)。

        *注:不同的组件之间传递信息涉及到数据格式和协议的转换

      整个流程如下图所示:

      nginx的作用:
        1. 第一级的nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程;
        2. 在nginx上加上安全性或其他的限制,可以达到保护程序的作用;
        3. uWSGI本身是内网接口,开启多个work和processes可能也不够用,而nginx可以代理多台uWSGI完成uWSGI的负载均衡;
        4. django在debug=False下对静态文件的处理能力不是很好,而用nginx来处理更加高效。

    3. 部署环境及准备

        购买服务器(国外谷歌云,亚马逊aws;国内阿里云,腾讯云等),需安装:python,django,uwsgi、nginx、libmysqld-dev、mysql-server;

      3.1. 安装和测试uWSGI  

    安装
    sudo pip install uwsgi
    
    测试:
    新建test.py,内容如下
    
    #/usr/bin/python
    def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return "Hello World"
    
    运行 uwsgi --http 0.0.0.0:8000 --wsgi-file test.py
    浏览器访问 http://127.0.0.1:8000   页面出现Hello World,则安装成功

    (问题:若8000端口被占用,换其他端口; uwsgi找不到命令,建立软连接 sudo ln -s /your-python-dir/bin/uwsgi /usr/bin/uwsgi)

      3.2  安装和测试nginx

        安装:sudo yum install nginx

        启动:sudo nginx         (ps -aux| grep nginx 查看nginx进程)

        测试:浏览器访问http://127.0.0.1:80 (命令行 curl http://127.0.0.1:80),返回nginx则运行正常

        其他nigix命令:

          启动:nginx  

          退出或重启:nginx -s stop(quit, reload)

          命令帮助: nginx -h

                验证配置文件 nginx -t

       3.3 建立django 项目和测试

        创建项目:django-admin.py startproject notebook  (找不到命令时 :/usr/local/python-3.5.2/bin/django-admin.py startproject notebook)

        创建app:python manage.py startapp planlist          (并在settings.py文件的INSTALLED_APPS中添加planlist.apps.PlanlistConfig)

        运行测试: python manage.py runserver 127.0.0.1:8000   (浏览器打开http://127.0.0.1:8000, 出现django页面,项目创建成功) 

          3.4 uWSGI运行django项目测试

        关闭上述django项目后,运行命令:uwsgi --http :8000 --module notebook.wsgi   

          (notebook为django项目名称,创建django项目时notebook文件夹下自动创建wsgi.py文件)

        测试:在浏览器访问http://127.0.0.1:8000,出现django页面,表示web-client <-> uWSGI <-> Django 是连通的。(就剩下nginx了)

        (注意:1. --http和 :8000之间有空格,否则会报错unrecognized ...

           2. 在项目根目录下运行上述命令,即notebook项目文件夹下,否则报错import error notebook.wsgi)

      3.5 nginx配置和测试

        找到nginx默认的配置文件路径:/etc/nginx/nginx.conf( 通过命令可以查看:sudo nginx -t),确保nginx.conf的同目录下有uwsgi_params文件(/etc/nginx/uwsgi_params),没有的话根据链接获取。

        在django项目目录下,创建单独的nginx配置文件notebook.conf (notebook/notebook/notebook.conf),将nginx.conf的内容复制到notebook.conf,将其中的server部分全部替换成下面:

    
    

    server {
            listen       80;
            server_name  localhost;
            charset       utf-8;
            access_log    /home/gCloud/djangoProject/notebook/notebook/nginx_access.log;
            error_log    /home/gCloud/djangoProject/notebook/notebook/nginx_error.log;
            client_max_body_size    75M;

            # Load configuration files for the default server block.

            location /static {
                    alias /home/gCloud/djangoProject/notebook/collect_static;
            }

            location / {
                    include /etc/nginx/uwsgi_params;
                    uwsgi_pass 127.0.0.1:9090;
        }

    }

         其中的 listen 80代表服务器开放80端口;

      access_log 和error_log是定义nginx访问日志和错误日志的存放路径。

      location [目录名]代表项目路径的引导;
        “location /static”中的”/static”是自己定义的项目引用静态文件时,浏览器中显示的静态资源所在的根目录名;这样的话,用户在浏览器中查看到的所有      image,css或js资源都是处在http://127.0.0.1/static下的。(django静态文件的绝对路径是根据自己的实际情况来确定的,一般在自己的django的app/static目录下,或自己python manage.py collectstatic后的路径下。)

      如果还有media文件之类的静态目录,仿照static的写法,自己补充。

      “location /”是指访问项目根目录时,nginx要做的事。其中需要指定 uwsgi_params文件的绝对路径,上面已经提到了;

      127.0.0.1:9090是指uWSGI绑定的监听地址,这里使用了9090端口。

      nginx配置参考及含义:

    # ocean_monitor.conf
    
    # the upstream component nginx needs to connect to
    upstream django_ocean_monitor {
        # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
        # for a web port socket (we'll use this first)
        server 127.0.0.1:8108;
    }
    
    # configuration of the server
    server {
        # the port your site will be served on
        listen      8008;
        # the domain name it will serve for
        # substitute your machine's IP address or FQDN
        # Django 的 settings.py 文件中的 ALLOWED_HOSTS 要加上这里设置的 server_name
        server_name localhost;
        charset     utf-8;
    
        gzip on;
        gzip_min_length 1000;
        gzip_buffers 4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 3;
        gzip_vary on;
        # 禁用对 IE 6 使用 gzip 压缩
        gzip_disable "MSIE [1-6].";
        gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/xml+rss application/json;
    
        ## Individual nginx logs
        access_log  /var/log/nginx/ocean_monitor_access.log;
        error_log   /var/log/nginx/ocean_monitor_error.log;
    
        # max upload size
        client_max_body_size 8M;   # adjust to taste
    
        # Django media
        location /media  {
            # your Django project's media files - amend as required
            alias /home/python/ocean_monitor/media;  
        }
    
        location /static {
            # your Django project's static files - amend as required
            alias /home/python/ocean_monitor/static; 
        }
    
        # Finally, send all non-media requests to the Django server.
        location / {
            uwsgi_pass  django_ocean_monitor;
            # the uwsgi_params file you installed
            #  增加 nginx 配置, uwsgi_params 文件在 /etc/nginx/ 目录下
            include     /etc/nginx/uwsgi_params; 
        }
    }
    nginx配置参考 

       3.6 django配置

          3.6.1静态文件

          在settings.py文件中设置:

            STATIC_URL = '/static/'

            STATIC_ROOT = os.path.join(BASE_DIR,'collect_static')

          运行命令:python manage.py collectstatic    (所有静态文件会储存到collect_static文件夹中)

          关于STATIC_ROOT和STATIC_URL及STATICFILES_DIRS作用和区别,参见下面

    本文主要给大家介绍关于Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
    
    详细如下:
    
    首先,我们配置静态文件,要在setting.py里面加入如下几行代码:
    
    settings.py    
    # the settings above
    # STATIC SETTINGS
    STATIC_URL = '/static/'
    # BASE_DIR 是项目的绝对地址
    STATIC_ROOT = os.path.join(BASE_DIR, 'collect_static')
    #以下不是必须的
    STATICFILES_DIRS = (
     os.path.join(BASE_DIR, 'common_static'),
    )
    
    1.STATIC_ROOT
    
    STATIC_ROOT 是在部署静态文件时(pyhtonmanage.pycollectstatic)所有的静态文静聚合的目录,STATIC_ROOT要写成绝对地址,在这里,比如我的项目mysite是/home/mysite/
    
    那么STATIC_ROOT 为 /home/mysite/collect_static/
    
    当部署项目时,在终端输入:
    ?
    1
        
    python manage.py collectstatic
    
    django会把所有的static文件都复制到STATIC_ROOT文件夹下
    
    2.STATICFILES_DIRS
    
    STATIC_ROOT 是在部署的时候才发挥作用, 而实际情况下,静态文件的一般安放位置有两种:
    
    1.一种就是在每个app里面新建一个static文件夹,将静态文件放到里面,在加载静态文件时,比如要在模板中用到静态文件,django会自动在每个app里面搜索static文件夹(所以,不要把文件夹的名字写错哦, 否则django就找不到你的文件夹了)
    
    2.另一种,就是在所有的app文件外面,建立一个公共的文件夹, 因为有些静态文件不是某个app独有的,那么就可以把它放到一个公共文件夹里面,方便管理(注意,建立一个公共的静态文件的文件夹只是一种易于管理的做法,但是不是必须的,app是可以跨app应用静态文件的,因为最后所有的静态文件都会在STATIC_ROOT里面存在)
    
    那现在的问题是如何让django知道你把一些静态文件放到app以外的公共文件夹中呢,那就需要配置STATICFILES_DIRS了
        
    STATICFILES_DIRS = (
     os.path.join(BASE_DIR, 'common_static'),
    )
    
    STATICFILES_DIRS告诉django,首先到STATICFILES_DIRS里面寻找静态文件,其次再到各个app的static文件夹里面找(注意, django查找静态文件是惰性查找,查找到第一个,就停止查找了)
    
    3.STATIC_URL
    
    那么到此为止,静态文件的机制就可以运作了,但是有一个问题,我能不能通过url直接访问我在项目中的静态文件呢,答案肯定是啦,但是,注意,你是在浏览器是访问,你不可能输入你的静态文件的本地绝对地址吧,比如我的一种图片的本地地址
    
    为 /home/mysite/common_static/myapp/photo.png
    
    那么别人不可能在浏览器上直接输入:
    
    http://192.168.1.2:8000/home/mysite/common_static/myapp/photo.png
    
    这样子,浏览器会报错, 没有该页面
    
    那么django是如何让浏览器也可以访问服务器上的静态文件呢,前面已经说了,直接访问服务器本地的地址是不行的,那就需要一个映射,django利用STATIC_URL来让浏览器可以直接访问静态文件,比如:
    ?
    1
        
    STATIC_URL = '/static/'
    
    那么可以在浏览器上输入:
    
    http://192.168.1.2:8000/static/common_static/myapp/photo.png
    
    那么就相当与访问/home/mysite/common_static/myap/photo.png
    
    所以在浏览器上,利用前缀 STATIC_URL的具体内容,来映射STATIC_ROOT,
    HTTP://192.168.1.2:8000/static 相当于 本地地址的STATIC_ROOT
    
    总结
    
    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
    STATIC_ROOT和STATIC_URL及STATICFILES_DIRS

         3.6.2 ALLOWED_HOSTS和DEBUG设置     

           修改settings.py文件中的ALLOWED_HOSTS和DEBUG (https://www.cnblogs.com/restran/p/4412708.html)

    DEBUG = False #关闭debug模式
    
    ALLOWED_HOSTS = [
        # 加上本机的IP地址
        '192.168.137.146',
        '127.0.0.1', 
        'localhost'
    ]
    
    #或者设置
    #ALLOWED_HOSTS = ['*']

      3.7 uWSGI配置   (官方文档:https://uwsgi-docs.readthedocs.io/en/latest/Management.html#signals-for-controlling-uwsgi)

        在项目目录下创建配置文件uwsgi.ini,内容如下:

    [uwsgi] 
    socket = 127.0.0.1:9090 
    chdir=/home/gCloud/djangoProject/notebook 
    module=notebook.wsgi 
    master = true         
    processes=2 
    threads=2 
    max-requests=2000 
    chmod-socket=664 
    vacuum=true 
    daemonize =/home/gCloud/djangoProject/notebook/uwsgi.log
    pidfile=%(chdir)/uwsgi.pid

        其中的socket字段值”127.0.0.1:9090”必须要和上面写的notebook.conf配置文件中的uWSGI监听地址完全一样;
        chdir指自己工程的绝对路径;
        module指的是wsgi.py在自己工程中的相对路径,”.”指代一层目录;我的django工程的wsgi.py文件是在”/home/gCloud/djangoProject/notebook/notebook /wsgi.py”,所以写notebook.wsgi;
        daemonize指定uWSGI日志的存储路径

        pidfile设置后,通过下面--ini命令启动uwsgi时,会在该目录下自动创建uwsgi.pid文件,里面存储了uwsgi的pid号(进程号)

        uwsgi配置参考及含义:

    # uwsgi.ini file
    [uwsgi]
    
    # Django-related settings
    # the base directory (full path)
    chdir           = /home/python/ocean_monitor
    # Django's wsgi file
    wsgi-file       = /home/python/ocean_monitor/ocean_monitor/wsgi.py
    # module       = index.wsgi:application
    # the virtualenv (full path)
    # home            = /path/to/virtualenv
    daemonize   = /home/python/ocean_monitor/ocean_monitor.log
    # process-related settings
    # master
    master          = true
    pidfile     = /tmp/ocean_monitor_master.pid
    # maximum number of worker processes
    processes       = 3
    # the socket (use the full path to be safe
    # socket          = /home/python/ocean_monitor/ocean_monitor.sock
    socket          = 127.0.0.1:8108
    # ... with appropriate permissions - may be needed
    chmod-socket    = 664
    # clear environment on exit
    vacuum          = true
    uwsgi配置参考

      3.8 启动uWSGI

        sudo uwsgi --ini /home/gCloud/djangoProject/notebook/uwsgi.ini

        其他命令:

          停止uwsgi服务器:sudo uwsgi --stop /home/gCloud/djangoProject/notebook/uwsgi.pid

          重启:sudo uwsgi --reload /home/gCloud/djangoProject/notebook/uwsgi.pid

          (如果出现错误 signal_pidfile()/kill(): No such process [core/uwsgi.c line 1627],是由于uwsgi.pid中进程pid号不正确,通过命令 ps -aux | grep uwsgi 查看进程pid号,修改uwsgi.pid文件为该pid号即可)

      3.9 启动 nginx

        sudo nginx -c /home/gCloud/djangoProject/notebook/notebook/notebook.conf 

        (注意若nginx正在运行,先关闭:sudo nginx -s stop)

      最后打开浏览器输入 http://127.0.0.1,就能访问django项目的网页了,每次修改django项目文件的代码需要重启uwsgi和nginx才生效。

       3.10 相关的文件路径梳理

        django项目路径: /home/gCloud/djangoProject/notebook  (项目名为notebook)

        工程静态文件路径:  /home/gCloud/djangoProject/notebook/collect_static

        wsgi.py的路径:  /home/gCloud/djangoProject/notebook/notebook/wsgi.py

        uwsgi.ini的路径: /home/gCloud/djangoProject/notebook/uwsgi.ini

        uwsgi日志路径: /home/gCloud/djangoProject/notebook/uwsgi.log

        uwsgi.pid路径:/home/gCloud/djangoProject/notebook/uwsgi.pid

        nginx配置文件notebook.conf的路径: /home/gCloud/djangoProject/notebook/notebook/notebook.conf

        uwsgi_params的路径: /etc/nginx/uwsgi_params

        nginx访问日志路径:/home/gCloud/djangoProject/notebook/notebook/nginx_access.log

        nginx错误日志路径: /home/gCloud/djangoProject/notebook/notebook/nginx_error.log

        项目路径完整显示如下:

    [gCloud@instance-1 notebook]$ ls -R
    .:
    collect_static  db.sqlite3  manage.py  notebook  planlist  templates  uwsgi.ini  uwsgi.log  uwsgi.pid
    
    ./collect_static:
    admin
    
    ./collect_static/admin:
    css  fonts  img  js
    
    ./collect_static/admin/css:
    base.css  changelists.css  dashboard.css  fonts.css  forms.css  login.css  rtl.css  widgets.css
    
    ./collect_static/admin/fonts:
    LICENSE.txt  README.txt  Roboto-Bold-webfont.woff  Roboto-Light-webfont.woff  Roboto-Regular-webfont.woff
    
    ./collect_static/admin/img:
    calendar-icons.svg  icon-calendar.svg    icon-no.svg           inline-delete.svg  selector-icons.svg
    gis                 icon-changelink.svg  icon-unknown-alt.svg  LICENSE            sorting-icons.svg
    icon-addlink.svg    icon-clock.svg       icon-unknown.svg      README.txt         tooltag-add.svg
    icon-alert.svg      icon-deletelink.svg  icon-yes.svg          search.svg         tooltag-arrowright.svg
    
    ./collect_static/admin/img/gis:
    move_vertex_off.svg  move_vertex_on.svg
    
    ./collect_static/admin/js:
    actions.js      cancel.js        core.js         popup_response.js    SelectBox.js      vendor
    actions.min.js  change_form.js   inlines.js      prepopulate_init.js  SelectFilter2.js
    admin           collapse.js      inlines.min.js  prepopulate.js       timeparse.js
    calendar.js     collapse.min.js  jquery.init.js  prepopulate.min.js   urlify.js
    
    ./collect_static/admin/js/admin:
    DateTimeShortcuts.js  RelatedObjectLookups.js
    
    ./collect_static/admin/js/vendor:
    jquery  xregexp
    
    ./collect_static/admin/js/vendor/jquery:
    jquery.js  jquery.min.js  LICENSE-JQUERY.txt
    
    ./collect_static/admin/js/vendor/xregexp:
    LICENSE-XREGEXP.txt  xregexp.js  xregexp.min.js
    
    ./notebook:
    __init__.py  nginx_access.log  notebook.conf  settings.py  wsgi.py
    mime.types   nginx_error.log   __pycache__    urls.py
    
    ./notebook/__pycache__:
    __init__.cpython-35.pyc  settings.cpython-35.pyc  urls.cpython-35.pyc  wsgi.cpython-35.pyc
    
    ./planlist:
    admin.py  apps.py  __init__.py  migrations  models.py  __pycache__  tests.py  views.py
    
    ./planlist/migrations:
    __init__.py  __pycache__
    
    ./planlist/migrations/__pycache__:
    __init__.cpython-35.pyc
    
    ./planlist/__pycache__:
    admin.cpython-35.pyc  apps.cpython-35.pyc  __init__.cpython-35.pyc  models.cpython-35.pyc  views.cpython-35.pyc
    
    ./templates:
    index.html
    notebook
    4. 管理进程

    https://code.ziqiangxuetang.com/django/django-deploy-base.html

    https://code.ziqiangxuetang.com/django/django-nginx-deploy.html

    5.阿里云部署

      1.远程连接设置:https://www.jianshu.com/p/962ff16a951c

      2.部署:按上述配置好django,uwsgi,nginx,本地通过127.0.0.1能访问网页,表示配置成功。

      3.入站和出站规则设置(安全组):https://blog.csdn.net/A11085013/article/details/79486731

      设置完成后通过实例公网ip地址就能访问网页(公网ip地址在django的allowed_host,nginx的端口80加入了入站规则)

    参考:https://blog.csdn.net/c465869935/article/details/53242126
      https://www.cnblogs.com/restran/p/4412708.html
      https://www.cnblogs.com/simplezy/p/6705340.html
  • 相关阅读:
    vue 拖拽移动(类似于iPhone虚拟home )
    鼠标事件-MouseEvent【转】
    JS快速排序 希尔排序 归并排序 选择排序
    JS 继承
    Centos6 iptables 防火墙设置【转】
    centos6 mongodb 安装
    操作系统中涉及的各种调度算法
    循环队列
    队列
    栈(C++)
  • 原文地址:https://www.cnblogs.com/silence-cho/p/10357603.html
Copyright © 2011-2022 走看看