Python后端部署-Part4——uWSGI与Nginx部署

[TOC]

uWSGI

WSGI 与 uWSGI

  • WSGI:
    • WSGI(Web Server Gateway Interface 或者 Python Web Server Gateway Interface),是为 Python 语言定义的 Web 服务器和 Web 应用或框架之间的一种简单而通用的接口。
    • WSGI,是网关(Gateway)。网关的作用就是在协议之间进行转换。
    • 很多框架都自带了 WSGI server,如 Flask、Django 等。但性能都不好,自带的 WebServer 更多的是测试用途,发布时则使用生产环境的 WSGI server。
  • uWSGI:
    • 是一个Web服务器,实现了 WSGI、uwsgi、http 等协议。
      • uwsgi 协议是 uWSGI 服务器自有的协议,用于定义传输信息的类型。
      • 每一个 uwsgi packet 前 4byte 为传输信息类型描述,uwsgi 与 WSGI 相比是两样东西。
    • Nginx 中 HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。
  • WSGI / uwsgi / uWSGI 区分:
    • WSGI 是一种通信协议。
    • uwsgi 同 WSGI 一样是一种通信协议。
    • uWSGI 是实现了 uwsgi 和 WSGI 两种协议的 Web 服务器。
  • 为什么有了 uWSGI 为什么还需要 nginx?
    • 因为 nginx 具备优秀的静态内容处理能力,然后将动态内容转发给 uWSGI 服务器,这样可以达到很好的客户端响应。

安装

1
2
pip install uwsgi	# 安装
uwsgi --version # 查看 uwsgi 版本

自定义配置文件(常用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[uwsgi]
# 项目所在的根目录
chdir = /data/WebService/backend
# 指定项目的application,启动程序文件
# wsgi-file = WebService/wsgi.py
module = WebService.wsgi
# 指定sock的文件路径,这个sock文件会在nginx的uwsgi_pass配置,用来nginx与uwsgi通信
# 支持 ip+port 模式以及 socket file 模式
# socket = %(chdir)/uwsgi_conf/uwsgi.sock
socket = 127.0.0.1:8000
# 指定IP端口,web访问入口
http = 0.0.0.0:8000
# 进程个数、线程数
processes = 2
threads = 4
# 每个进程worker数
workers = 5
# uwsgi的进程名称前缀
procname-prefix-spaced = WebService
# py文件修改,自动加载
py-autoreload = 1
# 指定多个静态文件:static目录和media目录,也可以不用指定该静态文件,在nginx中配置静态文件目录
# uwsgi有自己的配置语法,详细可参考官网,无需写绝对路径,可以用循环、判断等高级配置语法
for = static media
static-map = /static=%(chdir)/static
# 启动uwsgi的用户名和用户组
uid = root
gid = root
# 启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。
master = true
# 当服务停止的时候自动移除unix Socket和pid文件
vacuum = true
# 序列化接受的内容,如果可能的话
thunder-lock = true
# 启用线程
enable-threads = true
# 设置一个超时,用于中断那些超过服务器请求上限的额外请求
harakiri=30
http-timeout = 180
socket-timeout = 180
# 设置缓冲
post-buffering=4096
buffer-size = 65536
# 设置日志目录
daemonize=%(chdir)/uwsgi_conf/uwsgi.log
# uWSGI进程号存放
pidfile=%(chdir)/uwsgi_conf/uwsgi.pid
# monitor uwsgi status 通过该端口可以监控 uwsgi 的负载情况
# 支持 ip+port 模式以及 socket file 模式
# stats=%(chdir)/uwsgi_conf/uwsgi.status
stats = 127.0.0.1:9001
max-requests = 1000

指令(常用)

  • 启动 uWSGI:uwsgi --ini uwsgi.ini
  • 关闭 uWSGI:uwsgi --stop uwsgi.pid

管理静态文件

参考:https://note.qidong.name/2017/07/uwsgi-serve-django-static/

现象:

  • 在 uWSGI 下无法访问静态资源,而在 runserver 下则没有问题。

原因:

  • 一个 Django 应用,一般有两类静态文件。 一是应用内的静态文件,二是 Django 本身以及第三方库的静态文件
    • 应用内的静态文件:在与 settings.py 设定的 STATICFILES_DIRS 目录列表中。
    • Django 本身以及第三方库的静态文件:INSTALLED_APPS 中配置的 django.contrib.admin、rest_framework 等。
      • 例,admin 的静态文件在:/usr/local/lib/python3.6/site-packages/django/contrib/admin/static/admin/。
  • 因此 STATICFILES_DIRS 不仅包含了自己存放的应用内的静态文件,还隐含了 Django 本身以及第三方库的静态文件
  • 而 uWSGI 根本不知道静态文件在什么位置,只有 Django 自己知道。

解决:

  • 在 Django 的 setting.py 中配置:

    • ```python
      STATIC_ROOT = ‘./collectedstatic’ # /data/WebService/backend/collectedstatic
      STATIC_URL = ‘/static/‘
      STATICFILES_DIRS = ( # 不能与 STATIC_ROOT 重名
      os.path.join(BASE_DIR, 'static'),
      )
      1
      2
      3
      4
      5
      6
      7
      8
      9

      - 运行 Django 命令:`python3 manage.py collectstatic`

      - 把所有 STATICFILES_DIRS 目录下的文件,都复制到 STATIC_ROOT 中。

      - 在配置文件中添加:

      - ```ini
      static-map = /static=/data/WebService/backend/collectedstatic
    • 通常使用绝对路径,但也支持相对路径。
  • 启动 uWSGI :uwsgi --ini uwsgi.ini

Nginx

安装

  1. apt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       apt-get install nginx

    2. wget

    ```bash
    wget http://nginx.org/download/nginx-1.5.6.tar.gz
    tar xf nginx-1.5.6.tar.gz
    cd nginx-1.5.6
    ./configure --prefix=/usr/local/nginx-1.5.6 \
    --with-http_stub_status_module \
    --with-http_gzip_static_module
    make && make install
  2. 检查 nginx 是否安装、启动成功

    1
    2
    3
    4
    5
    6
    $ /etc/init.d/nginx start
    [ ok ] Starting nginx (via systemctl): nginx.service.
    $ ps -ef |grep -i nginx
    root 6961 1 0 03:56 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
    www-data 6962 6961 0 03:56 ? 00:00:00 nginx: worker process
    pala 6985 2090 0 03:57 pts/0 00:00:00 grep --color=auto -i nginx
  3. 打开浏览器,访问 ip 地址,可以看见 Welcome to nginx!

常用命令(常用)

  • 启动:/etc/init.d/nginx start
  • 关闭:/etc/init.d/nginx stop
  • 重启:/etc/init.d/nginx restart

自定义配置文件(常用)

  1. Nginx 的配置目录为 /etc/nginx/conf.d/ 或 /etc/nginx/sites-enabled/

  2. 创建配置文件:$ vim /etc/nginx/conf.d/xxx.conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    server{
    # 需要监听的端口
    listen 80;
    # 如果有域名就是买的域名
    server_name 0.0.0.0;
    # 日志配置
    access_log /var/log/nginx/access.log main;
    # 编码
    charset utf-8;

    # 启用压缩,这个的作用就是给用户一个网页,比如3M压缩后1M这样传输速度就会提高很多
    gzip on;
    # 支持压缩的类型
    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;

    # todo 加载静态文件的路径
    location /media {
    alias /data/WebService/backend/media; # your Django project's media files - amend as required
    }

    location /static {
    alias /data/WebService/backend/static; # your Django project's static files - amend as required
    }

    location /{
    # 在nginx里面的文件uwsgi_params
    include uwsgi_params;
    # 跟uwsgi通信的端口
    uwsgi_pass 127.0.0.1:8000;
    }
    }
  3. 若还未移动到目录下,则:cp /data/WebService/backend/nginx.conf /etc/nginx/sites-enabled/nginx.conf

  4. 重启 Nginx:$ /etc/init.d/nginx restart