• 使用nginx+uwsgi来部署django服务


    大体的流程是:nginx作为服务器最前端,负责接收client的所有请求,统一管理。静态请求由Nginx自己处理。非静态请求通过uwsgi传递给Django,由Django来进行处理,从而完成一次WEB请求。
    通信原理是:

    the web client <-> the web server(nginx) <-> the socket <-> uwsgi <-> Django

    1. 安装nginx

    sudo apt-get install nginx
    

    2. 安装uwsgi

    pip install uwsgi
    

    3. 测试uwsgi

    进入django项目根目录

    uwsgi --http :8001 --plugin python3 --module blog.wsgi
    

    然后访问127.0.0.1:8001检验uwsgi是否正常运行,注意这时项目的静态文件是不会被加载的,需要用nginx做静态文件代理。

    或者(可用)

    uwsgi --http 0.0.0.0:8888 --file mysite/wsgi.py --static-map=/static=static

    或者(可用)

    uwsgi --http :8000 --module TestDemo.wsgi

    4. 配置nginx

    vim /etc/nginx/site-enabled/default
    添加以下代码

    server {
        listen         80;
        server_name    域名;   # 如果没有域名就写ip地址
        charset UTF-8;
        access_log      /var/log/nginx/myweb_access.log;
        error_log       /var/log/nginx/myweb_error.log;
    
        location / {
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:8003;
            proxy_read_timeout 600;
        }
    
        location /static {
            alias static路径;
        }
    }
    
     

    5. 启动服务

    sudo /etc/init.d/nginx restart  # 重启nginx
    uwsgi --socket :8003 --plugin python3 --module blog.wsgi  # 启动uwsgi,注意这里是socket而不是http
    

    6. 出现问题

    1. 504 Gateway Time-out
      用http连接uwsgi可能出现504 Gateway Time-out,查看日志发现connect() failed (111: Connection refused) while connecting to upstream。把uwsgi启动时的参数http改成socket就好了,意思是如果nginx配置如果使用了uwsgi_pass指令,则uwsgi协议就只能用socket,具体如下:通常我们不会让浏览器直接与uWSGI通信。那是web服务器的工作,这是个穿针引线的活。
    2. 原因:nginx和uwsgi通信采用专门的socket协议。
     

    4、写uwsgi.ini配置文件

     1 #uwsgi.ini file
     2 [uwsgi]
     3 
     4 # Django-related settings
     5 # the base directory (full path)
     6 chdir           = /home/myself
     7 # Django's wsgi file
     8 module          = myself.wsgi:application
     9 # the virtualenv (full path)
    10 #home            = /path/to/virtualenv
    11  
    12 # process-related settings
    13 # master
    14 master          = true
    15 # maximum number of worker processes
    16 processes       = 3
    17 # the socket (use the full path to be safe)
    18 #socket          = /home/myself/myself.sock
    19 socket = 127.0.0.1:8001
    20 # ... with appropriate permissions - may be needed
    21 chmod-socket    = 666
    22 chown-socket = nginx:nginx
    23 # clear environment on exit
    24 vacuum          = true
    25 enable-threads = true


    修改nginx配置文件
    1 vim /etc/nginx/nginx/conf
    
    
    复制代码
      1 # For more information on configuration, see:
      2 #   * Official English Documentation: http://nginx.org/en/docs/
      3 #   * Official Russian Documentation: http://nginx.org/ru/docs/
      4 
      5 user nginx;
      6 worker_processes auto;
      7 error_log /var/log/nginx/error.log;
      8 pid /run/nginx.pid;
      9 
     10 # Load dynamic modules. See /usr/share/nginx/README.dynamic.
     11 include /usr/share/nginx/modules/*.conf;
     12 
     13 events {
     14     worker_connections 1024;
     15 }
     16 
     17 http {
     18     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
     19                       '$status $body_bytes_sent "$http_referer" '
     20                       '"$http_user_agent" "$http_x_forwarded_for"';
     21 
     22     access_log  /var/log/nginx/access.log  main;
     23 
     24     sendfile            on;
     25     tcp_nopush          on;
     26     tcp_nodelay         on;
     27     keepalive_timeout   65;
     28     types_hash_max_size 2048;
     29 
     30     include             /etc/nginx/mime.types;
     31     default_type        application/octet-stream;
     32 
     33     # Load modular configuration files from the /etc/nginx/conf.d directory.
     34     # See http://nginx.org/en/docs/ngx_core_module.html#include
     35     # for more information.
     36     include /etc/nginx/conf.d/*.conf;
     37 
     38     upstream django {
     39     #server unix:/home/myself/myself.sock; # for a file socket
     40     server 127.0.0.1:8001; # for a web port socket (we'll use this first)   ---socket
     41     }
     42 
     43     server {
     44         listen       80 default_server;
     45         listen       [::]:80 default_server;
     46         server_name  _;
     47         root         /usr/share/nginx/html;
     48 
     49         # Load configuration files for the default server block.
     50         include /etc/nginx/default.d/*.conf;
     51 
     52         location /static/ {
     53             root /home/myself;                                  ----project地址
     54         }
     55         
     56         location / {
     57             include uwsgi_params;
     58             uwsgi_pass django;                                  ----上面修改socket的位置
     59         }
     60 
     61         error_page 404 /404.html;
     62             location = /40x.html {
     63         }
     64 
     65         error_page 500 502 503 504 /50x.html;
     66             location = /50x.html {
     67         }
     68     }
     69 
     70 # Settings for a TLS enabled server.
     71 #
     72 #    server {
     73 #        listen       443 ssl http2 default_server;
     74 #        listen       [::]:443 ssl http2 default_server;
     75 #        server_name  _;
     76 #        root         /usr/share/nginx/html;
     77 #
     78 #        ssl_certificate "/etc/pki/nginx/server.crt";
     79 #        ssl_certificate_key "/etc/pki/nginx/private/server.key";
     80 #        ssl_session_cache shared:SSL:1m;
     81 #        ssl_session_timeout  10m;
     82 #        ssl_ciphers HIGH:!aNULL:!MD5;
     83 #        ssl_prefer_server_ciphers on;
     84 #
     85 #        # Load configuration files for the default server block.
     86 #        include /etc/nginx/default.d/*.conf;
     87 #
     88 #        location / {
     89 #        }
     90 #
     91 #        error_page 404 /404.html;
     92 #            location = /40x.html {
     93 #        }
     94 #
     95 #        error_page 500 502 503 504 /50x.html;
     96 #            location = /50x.html {
     97 #        }
     98 #    }
     99 
    100 }
    复制代码

    采用Systemd管理uwsgi
    1 mkdir -p /etc/uwsgi/ini
    2 mv /home/myself/uwsgi.ini /etc/uwsgi/ini/
    
    
    复制代码
     1 vim /etc/systemd/system/uwsgi.service
     2 
     3 
     4 [Unit]
     5 Description=uWSGI Emperor
     6 After=syslog.target
     7 
     8 [Service]
     9 ExecStart=/root/uwsgi/uwsgi --emperor /etc/uwsgi/ini
    10 Restart=always
    11 KillSignal=SIGQUIT
    12 Type=notify
    13 StandardError=syslog
    14 NotifyAccess=all
    15 
    16 [Install]
    17 WantedBy=multi-user.target
    复制代码

    nginx uwsgi_pass方式传递真实IP

    经过nginx反向代理后报文的源IP会改变,如果想要让后端的程序获取真实IP的话,需要修改NGINX配置,但是网上的方式都是使用proxy_pass的代理方式来修改的配置。对于uwsgi_pass方式来代理的并不生效。如果你的代理方式是proxy_pass的话,可以查看其它文章,随便一搜就可以搜到。
    如果使用uwsgi_pass代理的话,需要把你的nginx配置文件修改为以下内容(include和uwsgi_pass字段根据自己的情况填写):

    location /{      
            uwsgi_param X-Real-IP $remote_addr;
            uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
            uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
            include  /usr/local/nginx/uwsgi_params;
            uwsgi_pass $uwsgicluster:8001;       
        }


    在Django的后端程序中,如果获取真实IP,使用下面的字段去获取:

    request.META['X-Real-IP']


    如果获取不到的话,也可以先打印request.META所有内容,查看其它Key值是否有想要的内容。


    访问静态文件
    注意:如果你的项目为前后端分离的项目,也就是说前端是前端工程师来完成的,他们可能用了前端专有的一些框架,所以如果按前面那样进行操作的时候,会出现界面内容不显示的问题,这个问题主要是网页静态文件没有加载成功的原因,具体的操作办法为:

    (先关掉第三步中启动的服务)进入项目的setting.py文件中,添加如下内容:

      #setting.py文件中添加
      STATIC_ROOT = os.path.join(BASE_DIR, "static/")


    然后在之前的项目目录下执行:

        python manage.py collectstatic

    再重新启动uwsgi的命令,应该就可以成功访问页面了~




    关闭与开启服务:
     ps ax | grep uwsgi
    uwsgi --stop <uwsgi pid file>

    sudo /etc/init.d/nginx stop
    sudo /etc/init.d/nginx start




  • 相关阅读:
    融云会话界面导航上移-使用IQKeyboardManager
    App调用safar
    info.plist 安全登录
    could not find developer disk image
    easyExcel使用以及踩过的坑
    springBoot配置文件详解
    jvm面试题(纯手撸)
    面试题
    设计模式之观察者模式(Observer)
    设计模式之模板方法(TemplateMethod)
  • 原文地址:https://www.cnblogs.com/hongdoudou/p/12697186.html
Copyright © 2020-2023  润新知