Django + Uwsgi + Nginx 实现生产环境部署

一、概念

Django: 一个MVC架构的Web框架, 自带wsgi和server功能

Uwsgi: 一个高性能的cgi中间件,也提供Web服务器功能

nginx: 一个免费开源并且高性能的HTTP服务器和反向代理


二、为什么要用nginx

Django 和 Uwsgi 都提供服务器功能,的确nginx并不是必须,但是要部署到生产环境,需要考虑到某些情况

  1 、安全问题:程序不能直接被浏览器访问到,而是通过nginx,nginx只开放某个接口,uwsgi本身是内网接口,这样运维人员在nginx上加上安全性的限制,可以达到保护程序的作用。

  2、负载均衡问题:一个uwsgi很可能不够用,即使开了多个work也是不行,毕竟一台机器的cpu和内存都是有限的,有了nginx做代理,一个nginx可以代理多台uwsgi完成uwsgi的负载均衡。

  3、静态文件问题:用django或是uwsgi这种东西来负责静态文件的处理是很浪费的行为,而且他们本身对文件的处理也不如nginx好,所以整个静态文件的处理都直接由nginx完成,静态文件的访问完全不去经过uwsgi以及其后面的东西。

另外,Django虽然自带服务器功能,但性能不佳,仅仅用于测试开发阶段;uWsgi的服务器性功能没研究过,但它主要是一个Web服务器网关接口,服务器性能不是它的强项


三、为什么要用uWsgi

CGI中间件的性能见参考资料3,用uWsgi替换django自带的wsgi,提高服务性能


四、系统架构


五、安装

我是在MAC机上进行部署,使用安装工具HomeBrew,另外需要安装好Python3、pip、virtualenv 

1. 安装nginx、启动、验证

# 安装
brew install nginx
# 启动
brew services start nginx
# 验证
http://localhost:8080/
显示Welcome,证明nginx服务正常

注意: mac上nginx的安装目录在/usr/local/etc/nginx;  linux上目录为/etc/nginx

2. 安装uWsgi、启动、验证

# 安装
pip install uwsgi
# 新建test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2
# 启动
uwsgi --http :8000 --wsgi-file test.py
# 验证
http://localhost:8000
显示Hello World,证明安装成功

六、部署应用

1. 部署项目静态资源

# /path/to/your/site/site/settings.py
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
# 打包
python manage.py collectstatic
# 静态资源放到/path/to/your/site/static/

2. 创建Python虚拟环境: 每个Python有独立的运行

# /Users/Jason/Documents/pm-site/.env
cd /Users/Jason/Documents/pm-site
virtualenv 
virtualenv --no-site-packages .env
source .env/bin/activate
# 需要为虚拟环境安装django, 否则uwsgi起django项目时,会报错:No moduel "django"
pip install django

3. django 项目新增uwsgi 配置

# 创建your_site.sock文件,nginx与uwsgi通信使用
touch /Users/Jason/Documents/pm-site/pm_site/pm_site.sock
# 创建 /Users/Jason/Documents/pm-site/pm_site/uwsgi_params
# 内容从https://github.com/nginx/nginx/blob/master/conf/uwsgi_params 获取

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

#创建/Users/Jason/Documents/pm-site/pm_site/pm_site_uwsgi.ini
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /Users/Jason/Documents/pm-site/pm_site
# Django's wsgi file
module          = pm_site.wsgi
# the virtualenv (full path) 前面创建的虚拟环境
home            = /Users/Jason/Documents/pm-site/.env

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /Users/Jason/Documents/pm-site/pm_site/pm_site.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 777 # 注意了:这里必须设成777, 否则每次启动uwsgi会创建pm_site.sock(默认权限664), 守护进程启动时,nginx会报错没有权限
# clear environment on exit
vacuum          = true

注释:配置使用unix socket进行通信,比TCP socket性能要高(配置如下):

socket =127.0.0.1:8080 #对应nginx配置文件中的转发端口

4. django 项目新增nginx 配置

注释:nginx 配置也可以直接在/usr/local/etc/nginx/nginx.conf中配置,但是不方便部署

# 新建/Users/Jason/Documents/pm-site/pm_site/pm_site_nginx.conf,内容为:
# the upstream component nginx needs to connect to
upstream django {
    server unix:///Users/Jason/Documents/pm-site/pm_site/pm_site.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 172.25.220.166; # 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 /Users/Jason/Documents/pm-site/pm_site/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /Users/Jason/Documents/pm-site/pm_site/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     /Users/Jason/Documents/pm-site/pm_site/uwsgi_params; # the uwsgi_params file you installed
    }
}
# /usr/local/etc/nginx/nginx.conf 中有一句配置
include servers/*;

# 所以我们需要将项目的nginx配置放到servers/目录,让nginx可以找到
ln -s /Users/Jason/Documents/pm-site/pm_site_nginx.conf /usr/local/etc/nginx/services/

5. 启动服务

# 启动nginx
brew services start nginx
# 用uswgi 拉起django应用
uwsgi --ini /Users/Jason/Documents/pm-site/pm_site_uwsgi.ini

踩坑:修改nginx配置,必须使用nginx -s reload 读取配置才会生效, 我在部署时restart了好多次,都无效,各种排查

6. 自启动

 mac 和 linux 有所不同,自行查阅

七、总结

参考下面的资料,自行部署了一套服务,随笔记录踩过的坑

接下来研究一个ngnix 代理多个 django应用的场景

思路1: 1个Nginx + N 个(1个uwsgi + 1个django )

思路2: 1个Nginx + 1个uwsgi + N个django  (uwsgi vhost模式)

参考:

1)nginx uwsgi wsgi django 这些东西究竟是什么关系 https://blog.csdn.net/u014761344/article/details/40146597

2)Django为什么用uWSGI+Nginx  https://blog.csdn.net/qq_35318838/article/details/61198183

3)CGI中间件性能对比:http://developer.51cto.com/art/201010/229615.htm

4)基于nginx和uWSGI在Ubuntu上部署Django:https://www.jianshu.com/p/e6ff4a28ab5a

5)  使用uWSGI和nginx来设置Django和你的web服务 器: http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值