跳转至

Nginx+uWsgi部署Django

安装

sudo apt-get install nginx
sudo apt-get install python3-pip
# pip3 install uwsgi
python3.6 -m pip install uwsgi

配置

  1. 拷贝uwsgi_params
#将uwsgi_params拷贝到django项目文件夹下
cp /etc/nginx/uwsgi_params project_folder/django/
  1. project_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
    server unix:///django/TisaneMS/mysite.sock; # for a file socket
    #server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen 8000;
    # the domain name it will serve for
    server_name 192.168.1.2; # substitute your machine's IP address or FQDN
    charset utf-8;
    # max upload size
    client_max_body_size 75M; # adjust to taste
    # Django media
    location /media {
        alias /django/TisaneMS/media; # your Django project's media files - amend as required
    }
    location /static {
        alias /django/TisaneMS/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 /django/TisaneMS/uwsgi_params; # the uwsgi_params file you installed
    }
}
  1. 使用软链接开启站点:
sudo ln -s /path/to/your/mysite/project_nginx.conf /etc/nginx/sites-enabled/
  1. 配置文件 project_uwsgi.ini
[uwsgi]
# Django-related settings the base directory (full path)
chdir = /django/TisaneMS
# Django's wsgi file
module = TisaneMS.wsgi
# the virtualenv (full path)
home = /django/TisaneMS/environment
# process-related settings master
master = true
# maximum number of worker processes
processes = 4
# 多线程支持
enable-threads = true
# the socket (use the full path to be safe
socket = /django/TisaneMS/mysite.sock
# ... with appropriate permissions - may be needed chmod-socket = 664 clear environment on exit
  1. 运行uwsgi:
uwsgi --ini project_uwsgi.ini

生产环境下需要使用nohup command &或者supervisord来运行该命令以保证其一直处于后台运行的状态。

Https支持

基础配置:

server {
    listen 80;
    listen [::]:80;
    server_name demo.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443;
    server_name demo.example.com;

    ssl on;
    ssl_certificate /etc/nginx/cert/materia_tisane_cn/1542222634451.pem;
    ssl_certificate_key /etc/nginx/cert/materia_tisane_cn/1542222634451.key;

    root /django/Materia_Web;
    index index.html;
}

如果提示key不匹配,可使用openssl工具核对:

openssl x509 -noout -modulus -in demo.crt | openssl md5
openssl rsa -noout -modulus -in demo.key | openssl md5

并发

设平均响应时间为t(单位为毫秒), 并发量为c,每秒处理请求数为q,则:

q = (1000/t) * c 

负载均衡

Nginx负载均衡配置

uwsgitop状态监控

这是一个用于查看uwsgi运行状态的插件,详细文档见uwsgi at githb

Note

  • 可能需要修改/etc/nginx/nginx.conf中的userroot.

  • Nginx和uWsgi之间有Web Socket和File Socket两种通讯方法,推荐使用File Socket。

  • 全局安装uwsgi时,需要版本默认的python版本和virtualenv对应的版本相同,不然会出现可以在virtualenv中开启uwsgi而不可全局开启uwsgi的错误,报错信息为:

Traceback (most recent call last):
  File "./TisaneMS/wsgi.py", line 12, in <module>
    from django.core.wsgi import get_wsgi_application
ImportError: No module named 'django'

若全局python版本和virtualenv对应的python版本不同,可用以下命令指定安装时使用的py版本:

pip is bundled with Python > 3.4

On Unix-like systems use:

    python3.6 -m pip install [Package_to_install]

On a Windows system use:

    py -m pip install [Package_to_install]

可以使用 uwsgi --python-version 查看当前编译uwsgi使用的python版本

  • 开启站点一般使用软链接的方式将sites-available目录下的conf文件链接到sites-enabled目录下。
ln -s /etc/nginx/sites-available/tisanepms_web.conf /etc/nginx/sites-enabled/
  • 配置静态网站(如VUE)
server {
    listen 80;
    server_name clinicis.tisane.cn;

    root /django/TisanePMS_Web;
    index index.html;
}
  • uwsgi.ini参数说明

threads help: run each worker in prethreaded mode with the specified number of threads

processes help: spawn the specified number of workers/processes

  • 开启站点时生成的文件无法读取(带中横线) 路径必须由根目录开始
sudo ln -s /etc/nginx/sites-available/materia_wechat.conf /etc/nginx/sites-enabled/
  • nginx配置属性

client_max_body_size 50m;项是用于设置 http 请求的 body 最大大小。如果你的程序中有文件上传的,那么就需要根据自身情况来设置允许上传文件的最大值。

  • invalid request block size: 4126 (max 4096)

uwsgi设置buffer-size=32768;,详见StackOverflow

  • 私有文件保护

如该文件夹名称为 protected,示例代码如下:

file_path = os.path.join(settings.BASE_DIR, 'protected/')
file_name = os.path.join(settings.BASE_DIR, 'protected/stock.xlsx')
if not os.path.exists(file_path):
    os.mkdir(file_path)
wb.save(file_name)
wb.close()
file = open(file_name, 'rb').read()
if settings.DEBUG:
    response = HttpResponse(file, content_type='application/force-download')
else:
    response = HttpResponse(content_type='application/force-download')
    response['X-Accel-Redirect'] = '/protected/stock.xlsx'
response['Content-Disposition'] = 'attachment; filename={}'.format(urlquote('ExcelDemo.xlsx'))
return response

Nginx配置为:

location /protected/ {
  internal;
  alias /django/Materia/protected/;
}

若下载文件时出现CORS错误,Nginx配置请修改为:

location /protected/ {
  internal;
  add_header Access-Control-Allow-Origin *;
  alias /django/Materia/protected/;
}

以允许转发的请求头进行跨域访问。

  • Access Log记录请求用时

默认的log_format为:

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

log_format可选参数如下:

参数                      说明                                         示例
$remote_addr             客户端地址                                    211.28.65.253
$remote_user             客户端用户名称                                --
$time_local              访问时间和时区                                18/Jul/2012:17:00:01 +0800
$request                 请求的URI和HTTP协议                           "GET /article-10000.html HTTP/1.1"
$http_host               请求地址,即浏览器中你输入的地址(IP或域名)     www.wang.com 192.168.100.100
$status                  HTTP请求状态                                  200
$upstream_status         upstream状态                                  200
$body_bytes_sent         发送给客户端文件内容大小                        1547
$http_referer            url跳转来源                                   https://www.baidu.com/
$http_user_agent         用户终端浏览器等信息                           "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; GTB7.0; .NET4.0C;
$ssl_protocol            SSL协议版本                                   TLSv1
$ssl_cipher              交换数据中的算法                               RC4-SHA
$upstream_addr           后台upstream的地址,即真正提供服务的主机地址     10.10.10.100:80
$request_time            整个请求的总时间                               0.205
$upstream_response_time  请求过程中,upstream响应时间                    0.002

修改为:

log_format timed_combined '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '$request_time $upstream_response_time $pipe';

最后的Nginx配置:

log_format timed_combined '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '$request_time $upstream_response_time $pipe';

# configuration of the server
server {
    # the port your site will be served on
    listen 80;

    access_log /django/log/access.log timed_combined;
    ...
}

这样即可在access_log中看到此次请求的处理时长。