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
  • 相关阅读:
    剑指offer——最小的K个数和数组中第K大的元素
    Leetcode刷题指南链接整理
    160. Intersection of Two Linked Lists
    100. Same Tree
    92. Reverse Linked List II
    94. Binary Tree Inorder Traversal
    79. Word Search
    78,90,Subsets,46,47,Permutations,39,40 DFS 大合集
    0x16 Tire之最大的异或对
    0x16 Tire
  • 原文地址:https://www.cnblogs.com/silence-cho/p/10357603.html
Copyright © 2011-2022 走看看