Nginx+Django+uWSGI部署服务器详细解析

本文基于: 阿里云CentOS 7.4.1708, Python 3.6.1, Django 2.0.2, uWSGI 2.0.15, Nginx 1.12.2


知道怎么样部署之前我们要先弄清楚为什么? 为什么要用Django+uWSGI+Nginx? 所以更首先我们要知道是什么?

先弄清楚几点概念, 注意大小写区别.

  • WSGI - 全称为Python Web Server Gateway Interface, 即Python服务器网关接口. 是为Python语言定义的Web服务器Web应用程序Web应用框架之间的一种简单而通用的接口. WSGI只是一种通信协议. 更详细信息请查看维基百科WSGI.
    通俗一点说就是写Python程序时不想花费大量的时间去处理TCP连接、HTTP的请求和响应等等, 于是就把这些都统一成了一个接口(即WSGI). 然后由专门的Web服务器(uWSGI等)Web应用框架(Django等)去实现. 既降低了开发门槛又节约了时间.

  • uWSGI - uWSGI是一个实现了WSGI协议的Web服务器, uWSGI处理了HTTP的响应解析等, 并转成WSGI协议, 这样我们编写的Web应用程序或Web应用框架才可以对传递过来的信息进行处理.

  • uwsgi - uwsgi是实现了WSGI协议的服务器的内部自有协议, 它定义了传输信息的类型, 用于实现了WSGI协议的服务器与其他网络服务器的数据通信.


了解了基本的概念之后, 就知道了为什么要Django+uWSGI. Django是Python的Web应用框架, 他帮我们做了很多基础工作, 让开发者可以专心的写业务代码. 而uWSGI是实现了WSGI协议的Web服务器, 只有这两者组合在一起, Python的应用程序才可以发挥作用.

理论上, 有了这一套, 就可以部署到服务器使用了. 而我们还要加上Nginx的原因, 当然是因为Nginx可以做一些uWSGI做不到的事情, 或者把事情做得更好.

Nginx是一款面向性能设计的HTTP服务器,相较于Apache具有占有内存少,稳定性高等优势. 可以被用作反向代理负载平衡器HTTP缓存. 所以使用Nginx的最大原因之一就是性能问题. 如果只是个小网站, 不会有很大了流量, 当然uWSGI可以满足要求, 但是在高并发情况下就需要Nginx了, 并且Nginx相比Apache有很大的高并发优势.

另外, Nginx能带来更好的安全性. 并且可以直接处理静态内容, 不需要通过uWSGI, 让uWSGI专心处理动态内容, 从而提高性能. 更多Nginx内容可以访问Nginx, epoll, about Nginx.

总结一下各自的任务以及工作原理: Nginx接收到客户端的请求, 如果请求的是静态内容就直接返回静态内容, 如果请求的是动态内容, 就把请求转发给uWSGI ,uWSGI连接Django进入我们的Python程序进行处理.


知道了Django, uWSGI, Nginx分别是什么, 并且知道了为什么要用Django+uWSGI+Nginx之后, 就可以进行服务器的部署工作了.

  1. 在服务器部署Python 3.6和Django 2.0.2

  2. 连接阿里云服务器. 在Mac终端输入$ SSH root@xxx.cn, root是用户名xxx.cn是服务器域名或者IP地址

  3. 安装Nginx

    # yum install epel-release
    # yum install python-devel nginx
    
  4. 使用pip安装uwsgi >>> pip3 install uwsgi --upgrade

  5. 配置uWSGI和Nginx配置文件并直接放在项目根目录

    • 因为配置文件只需要在部署时使用一次, 直接在服务器配置会更合适. 当然你也可以在本地的项目文件夹新建对应的配置文件并写入配置. 但是需要注意配置文件中的路径都是服务器端的路径.

    • uWSGI配置文件uwsgi.ini. 更多信息请查看uWSGI Configuration.

      [uwsgi]
      #使用HTTP访问的端口号, 使用这个端口号是直接访问了uWSGI, 绕过了Nginx
      http = :8010
      #与外界连接的端口号, Nginx通过这个端口转发给uWSGI
      socket = 127.0.0.1:8001
      #是否使用主线程
      master = true
      # 项目在服务器中的目录(绝对路径)
      chdir = /project_dir/
      # Django's wsgi 文件目录
      wsgi-file = project_name/wsgi.py
      # 最大进程数
      processes = 4
      #每个进程的线程数
      threads = 2
      #状态监听端口
      stats = 127.0.0.1:9191
      # 退出时自动清理环境配置
      vacuum = true
      #目录下文件改动时自动重启
      touch-reload = /project_dir
      #Python文件改动时自动重启
      #py-auto-reload = 1
      #后台运行并把日志存到.log文件
      daemonize = /project_dir/uWSGI.log
      
    • Nginx需要两个配置文件. uwsgi_params文件和project_name.conf文件

      1. uwsgi_params文件可以直接在Nginx的git仓库中可以下载.

      2. project_name.conf通过复制nginx.conf配置文件并进行修改. 首先查找nginx.conf文件的位置:
        # nginx -t
        会打印出类似信息:

      nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      nginx: configuration file /etc/nginx/nginx.conf test is successful
      
      1. 新建project_name.conf文件, 复制nginx.conf文件的所有信息到project_name.conf. 并替换掉server部分内容.
        server {
        #把nginx.conf这一部分内容替换掉
        ...
        }
        
        替换之后的文件为:
        # For more information on configuration, see:
        #   * Official English Documentation: http://nginx.org/en/docs/
        #   * Official Russian Documentation: http://nginx.org/ru/docs/
        
        user  nginx;
        worker_processes  auto;
        error_log /var/log/nginx/error.log;
        pid /run/nginx.pid;
        
        # Load dynamic modules. See /usr/share/nginx/README.dynamic.
        include /usr/share/nginx/modules/*.conf;
        
        events {
            worker_connections  1024;
        }
        
        http {
            log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
            ¦   ¦   ¦   ¦   ¦ '$status $body_bytes_sent "$http_referer" '
            ¦   ¦   ¦   ¦   ¦ '"$http_user_agent" "$http_x_forwarded_for"';
        
            access_log  /var/log/nginx/access.log  main;
        
            sendfile            on;
            tcp_nopush          on;
            tcp_nodelay         on;
            keepalive_timeout   65;
            types_hash_max_size 2048;
        
            include             /etc/nginx/mime.types;
            default_type        application/octet-stream;
        
            # Load modular configuration files from the /etc/nginx/conf.d directory.
            # See http://nginx.org/en/docs/ngx_core_module.html#include
            # for more information.
            include /etc/nginx/conf.d/*.conf;
        
        
            #下面的部分是替换之后的配置
            # the upstream component nginx needs to connect to
            upstream django {
                # 连接到Django的端口号, 和uwsgi.ini文件中端口一致. 127.0.0.1说明只允许本地转发
                server 127.0.0.1:8001; # for a web port socket (we'll use this first)
            }
        
            # configuration of the server
            server {
                # 端口号, 客户端通过这个端口连接到Nginx
                listen      80;
                # 服务器地址
                server_name pefami.cn; # substitute your machine's IP address or FQDN
                # 编码
                charset     utf-8;
        
                #日志文件在服务器中的路径
                access_log      /project_dir/nginx_access.log;
                error_log       /project_dir/nginx_error.log;
        
                # 上传文件最大体积限制
                client_max_body_size 75M;   # adjust to taste
        
                # Django media文件路径
                location /media  {
                    alias /project_dir/media;  # your Django project's media files - amend as                         required
                }
                # Django 静态文件路径
                location /static {
                    alias /project_dir/static; # your Django project's static files - amend as required
                }
        
                # Finally, send all non-media requests to the Django server.
                location / {
                    uwsgi_pass  django;
                    include     /project_dir/uwsgi_params; # the uwsgi_params file you installed
                }
            }
        
        }
        
  6. 配置好了配置文件以后, 把项目整个上传到服务器. 接下来只要在服务器运行uWSGINginx就可以了. 这个有个需要注意: 在阿里云服务器打开对应端口, 比如上边配置中使用了的800180端口. 否则客户端无法连接上服务器.

  7. 启动uWSGI
    # uwsgi --ini uwsgi.ini
    也可以不需要配置文件直接启动uWSGI, 这时就不需要配置uwsgi.ini文件. 如下:
    # uwsgi --http :8001 --chdir /project_dir/project_name --home=/path/to/env --module project_name.wsgi
    其中--home指定virtualenv路径,如果没有可以去掉.

  8. 启动Nginx
    # nginx -c /project_dir/static/project_name.conf

  9. 启动完成之后可以查看一下网络端口的状态
    # netstat -nltp
    正常情况下回打印出类似下列信息. 显示uwsginginx是处于服务状态的.

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      18977/./src/redis-s 
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4752/nginx: master  
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1117/sshd           
    tcp        0      0 127.0.0.1:32000         0.0.0.0:*               LISTEN      969/java            
    tcp        0      0 127.0.0.1:8001          0.0.0.0:*               LISTEN      8989/uwsgi          
    tcp        0      0 127.0.0.1:9191          0.0.0.0:*               LISTEN      8989/uwsgi          
    tcp        0      0 0.0.0.0:8010            0.0.0.0:*               LISTEN      8989/uwsgi          
    tcp6       0      0 :::3306                 :::*                    LISTEN      1145/mysqld 
    
  10. 到这里, 部署的全过程就完成了.

  11. 另外, 修改了文件之后, Nginx需要重新启动:
    # nginx -s reload


因笔者知识有限, 如有错误, 欢迎指正.
转载请注明作者出处.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容