使用Nginx+uWsgi实现Python的Django框架站点动静分离


Posted in Python onMarch 21, 2016

由于:

Django处理静态文件不太友好;
以后有可能需要处理php或者其他资源的请求;

所以考虑结合nginx,使用nignx做它擅长的路由分发功能;同时做动静分离,即Http请求统一由Nginx进行分发,静态文件由Nginx处理,并返回给客户端;而动态的请求,则分发到uWsgi,由uWsgi再分发给Django进行处理。即客户端 <-> nginx <-> socket <-> uwsgi <-> Django

一、环境

系统:centOS 6

  • python: 2.7(注意:Django要在2.7版本或以上的python来 )
  • nginx
  • uswgi

所以,安装前,先在控制台输入python —version查看当前python的默认版本,如果在2.7以下,则修改默认版本。(详见附录)

二、安装nginx、uWsgi

安装

nginxsudo yum install nginx

安装

pipsudo yum install python-pip

安装

uWsgisudo pip uwsgi

三、测试nginx、uWsgi
1. 测试nginx启动测试nginx,看是否安装成功启动 sudo service nginx start然后在浏览器中,输入ip地址,看是否出现nginx的欢迎页面,出现则说明安装成功
2. 测试uWsgi在服务器上做任意目录下(一般在home下的某一目录),新建test.py,如下:

# test.pydef 
application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "Hello World"

启动以Http方式访问的uWsgi,在test.py同一目录下,输入如下命令行(8001是监听的端口,可以改成你想要的端口)

uwsgi --http :8001 --wsgi-file test.py

然后在浏览器中,输入ip地址:8001,看是否响应hello world,是则说明安装成功
P.S. 由于开始时,uwsgi的安装使用了错误的python版本,所以在我的服务器上,uwsgi正确地可执行命令暂时是:/usr/src/download/uwsgi-2.0.10/uwsgi即完整的命令行是(本文所有的uwsgi命令同此):/usr/src/download/uwsgi-2.0.10/uwsgi --http :8001 --wsgi-file test.py
--http :8001 --wsgi-file test.py至此,uwsgi和nginx安装成功。接下来把nginx、uwsgi、django关联起来。在它们的协作之下,达到我们想要的目标。

四、连接Django和uWsgi
如上uWsgi的测试那样,uWsgi监听8001端口,并把请求分发给test.py,python会执行这个文件,如果我们把test.py分给Django的入口文件,那么就实现了Django和uWsgi的连接。所以,要做的事情有两步:

在项目目录下创建wsgi.py文件
启动uWsgi,使用它的wsgi-file指向wsgi.py

wsgi.py内容如下:

"""
WSGI config for WHPAIWechat project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""

import osfrom django.core.wsgi import 
get_wsgi_applicationos.environ.setdefault("DJANGO_SETTINGS_MODULE", "WHPAIWechat.settings")
application = get_wsgi_application()

启动以Http方式访问uWsgiuwsgi --http :8000 --chdir /home/jiayandev/WHPAIWechat/ --wsgi-file WHPAIWechat/wsgi.py
浏览器访问 ip地址:8000,加上必要的路由,即可访问之前写好的python程序:例如[http://112.74.73.31:8000/wechat/call]
P.S. 你是否关注到,启动uwsgi即可,而无需再启动Django了?

五、连接uWsgi和nginx
接下来,打通 uWsgi和 nginx之间的连接,它们是通过socket来连接的。第四节所讲的链接 swgi和Django,我们用浏览器访问是能得到正确的响应的,说明连接成功。那么只要在nginx上,实现某些规则下,把前端的请求转发到此端口即可。要做的事情非常简单,即配置nginx的配置文件即可,一般在 /etc/nginx/conf.d/default.conf中。这里,我只设置几条简单的规则

url包含.css、.js等服务器特定目录,设置根目录
以上都不匹配的的访问分发到uwsgi上的, nginx转发给uswgi处理

更多规则可以视业务情况而定,完整的配置如下:

upstream django {
  server 127.0.0.1:8000; # 注意8000是上述uwsgi监听的端口
}
server {
  listen    80 default_server;
  server_name _;

  #charset koi8-r;

  #access_log logs/host.access.log main;

  # Load configuration files for the default server block.
  include /etc/nginx/default.d/*.conf;

  location = /404.html {
    root  /usr/share/nginx/html;
  }

  # redirect server error pages to the static page /50x.html
  #
  error_page  500 502 503 504 /50x.html;
  location = /50x.html {
    root  /usr/share/nginx/html;
  }

  location ~ \.html$ {
        root /usr/share/nginx/html/front;
        index index.html index.htm;
  }

   location ~ \.(png|jpg|jpeg|css|img|js|flv|swf|download|eot|svg|ttf|woff|woff2|otf)$ {
        root /usr/share/nginx/html/front;
  }


  # 以上都不匹配的的访问分发到uwsgi上
  location / {
    include    /etc/nginx/uwsgi_params; #详细看下文
    uwsgi_pass   django;
  }

  * # PHP分到 9000端口**
  #
  #location ~ \.php$ {
  #  root      html;
  #  fastcgi_pass  127.0.0.1:9000;
  #  fastcgi_index index.php;
  #  fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
  #  include    fastcgi_params;
  #}*
}

同时,uswgi_param内容如下,照抄即可

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 REMOTE_ADDR    $remote_addr;
uwsgi_param REMOTE_PORT    $remote_port;
uwsgi_param SERVER_PORT    $server_port;
uwsgi_param SERVER_NAME    $server_name;

配置完成后,重启或者reload nginx配置即可生效
重启:

sudo service nginx restart

reload:

sudo service nginx reload

然后直接访问,看看有什么不一样:
http://youIP/front/index.html
http://youIP/statics/index.html
http://youIP/(加上路由信息),例如 http://112.74.73.31/wechat/call
我们这里主要先关注访问django,如果http://112.74.73.31/wechat/call返回的信息跟第四节的一样,说明nginx和uwsgi也连接起来了,至此,nginx、uwsgi、django顺利连接完成。

六、优化uwsgi的启动
第三节、第四节介绍的启动uwsgi服务时,我们都是使用命令行的方式启动和设置参数的,这样不好记,有可能会忘记参数 等等。这里介绍另一种设置参数的方式,即用配置文件记录uwsgi的参数,启动时,从配置文件里加载参数。参数如下

#WHPAIWechat_uwsgi.ini[uwsgi]
socket = 127.0.0.1:8000
chdir = /home/jiayandev/WHPAIWechat/
wsgi-file = WHPAIWechat/wsgi.py
processes = 4
threads = 2
master=True #设置此参数,有一个主进程
pidfile= pidfile/project-master.pid #主进程id写入文件里
vacuum=True #退出时,清理环境
daemonize = uwsgi.log #守护进程的方式运行,log日志存在此log文件里

启动uwsgi命令变成uwsgi WHPAIWechat_uwsgi.ini

Python 相关文章推荐
Python删除指定目录下过期文件的2个脚本分享
Apr 10 Python
python简单实现旋转图片的方法
May 30 Python
Queue 实现生产者消费者模型(实例讲解)
Nov 13 Python
Jupyter安装nbextensions,启动提示没有nbextensions库
Apr 23 Python
使用Python设计一个代码统计工具
Apr 04 Python
Pandas分组与排序的实现
Jul 23 Python
python列表返回重复数据的下标
Feb 10 Python
Python selenium爬取微信公众号文章代码详解
Aug 12 Python
基于python爬取梨视频实现过程解析
Nov 09 Python
Opencv实现二维直方图的计算及绘制
Jul 21 Python
深入理解Pytorch微调torchvision模型
Nov 11 Python
python如何将mat文件转为png
Jul 15 Python
Python中的条件判断语句与循环语句用法小结
Mar 21 #Python
举例讲解Python中的迭代器、生成器与列表解析用法
Mar 20 #Python
深入解析Python中函数的参数与作用域
Mar 20 #Python
总结Python编程中函数的使用要点
Mar 20 #Python
两个命令把 Vim 打造成 Python IDE的方法
Mar 20 #Python
Python中列表、字典、元组数据结构的简单学习笔记
Mar 20 #Python
Python的Socket编程过程中实现UDP端口复用的实例分享
Mar 19 #Python
You might like
PHP 计算代码执行耗时的代码修正网上普遍错误
2011/05/14 PHP
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
PHP上传图片类显示缩略图功能
2016/06/30 PHP
JavaScript修改css样式style动态改变元素样式
2013/12/16 Javascript
JavaScript获取页面中第一个锚定文本的方法
2015/04/03 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
javascript实现滚动效果的数字时钟实例
2016/07/21 Javascript
js复制内容到剪贴板代码,js复制代码的简单实例
2016/10/27 Javascript
vue多级多选菜单组件开发
2020/09/08 Javascript
JS实现物体带缓冲的间歇运动效果示例
2016/12/22 Javascript
简单实现AngularJS轮播图效果
2020/04/10 Javascript
微信小程序progress组件使用详解
2018/01/31 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
2018/02/11 Javascript
nodejs简单读写excel内容的方法示例
2018/03/16 NodeJs
微信小程序实现简单评论功能
2018/11/28 Javascript
vue 验证码界面实现点击后标灰并设置div按钮不可点击状态
2019/10/28 Javascript
[01:52]2020年DOTA2 TI10夏季活动预告片
2020/07/15 DOTA
Centos7 Python3下安装scrapy的详细步骤
2018/03/15 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
详解Django将秒转换为xx天xx时xx分
2019/09/27 Python
Python 3.8 新功能大揭秘【新手必学】
2020/02/05 Python
CSS3实现苹果手机解锁的字体闪亮效果示例
2021/01/05 HTML / CSS
雅诗兰黛美国官网:Estee Lauder美国
2016/07/21 全球购物
W Concept美国:精选全球独立设计师
2017/02/22 全球购物
Java基础知识面试要点
2016/07/29 面试题
餐饮业创业计划书范文
2014/01/06 职场文书
协议书怎么写
2014/04/21 职场文书
企业文化演讲稿
2014/05/20 职场文书
银行服务明星推荐材料
2014/05/29 职场文书
楚门的世界观后感
2015/06/03 职场文书
旷工检讨书大全
2015/08/15 职场文书
如何书写公司员工保密协议?
2019/06/27 职场文书
redis实现排行榜功能
2021/05/24 Redis
html2 canvas svg不能识别的解决方案
2021/06/03 HTML / CSS
Python中npy和mat文件的保存与读取
2022/04/24 Python
阿里云服务器(windows)手动部署FTP站点详细教程
2022/08/05 Servers