使用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 相关文章推荐
Python3 操作符重载方法示例
Nov 23 Python
python抓取网页中链接的静态图片
Jan 29 Python
用Python写一段用户登录的程序代码
Apr 22 Python
Python全局变量与局部变量区别及用法分析
Sep 03 Python
Python连接Redis的基本配置方法
Sep 13 Python
用Python读取几十万行文本数据
Dec 24 Python
python监控进程状态,记录重启时间及进程号的实例
Jul 15 Python
Python在OpenCV里实现极坐标变换功能
Sep 02 Python
在python tkinter界面中添加按钮的实例
Mar 04 Python
详解Anaconda安装tensorflow报错问题解决方法
Nov 01 Python
Python Django ORM连表正反操作技巧
Jun 13 Python
Python Matplotlib绘制两个Y轴图像
Apr 13 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第一季视频教程(李炎恢+php100 不断更新)
2011/05/29 PHP
php生成验证码函数
2015/10/20 PHP
不用MOUSEMOVE也能滑动啊
2007/05/23 Javascript
使用Chrome调试JavaScript的断点设置和调试技巧
2014/12/16 Javascript
理解javascript回调函数
2014/12/28 Javascript
jQuery之DOM对象和jQuery对象的转换与区别分析
2015/01/08 Javascript
cocos2dx骨骼动画Armature源码剖析(三)
2015/09/08 Javascript
JavaScript必知必会(六) delete in instanceof
2016/06/08 Javascript
基于JavaScript实现前端数据多条件筛选功能
2020/08/19 Javascript
Node.js readline 逐行读取、写入文件内容的示例
2018/03/01 Javascript
全网小程序接口请求封装实例代码
2020/11/06 Javascript
python中getattr函数使用方法 getattr实现工厂模式
2014/01/20 Python
python3中str(字符串)的使用教程
2017/03/23 Python
python爬取w3shcool的JQuery课程并且保存到本地
2017/04/06 Python
spyder常用快捷键(分享)
2017/07/19 Python
20个常用Python运维库和模块
2018/02/12 Python
Python登录注册验证功能实现
2018/06/18 Python
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
Python3.4解释器用法简单示例
2019/03/22 Python
pycharm创建scrapy项目教程及遇到的坑解析
2019/08/15 Python
Python彻底删除文件夹及其子文件方式
2019/12/23 Python
python读取hdfs上的parquet文件方式
2020/06/06 Python
flask项目集成swagger的方法
2020/12/09 Python
详解html5 postMessage解决跨域通信的问题
2018/08/17 HTML / CSS
英国百安居装饰建材网上超市:B&Q
2016/09/13 全球购物
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
2014年自我评价
2014/01/04 职场文书
网站美工岗位职责
2014/04/02 职场文书
爱情保证书
2015/01/17 职场文书
书法社团活动总结
2015/05/07 职场文书
2015年妇委会工作总结
2015/05/22 职场文书
2015最新民情日记范文
2015/06/26 职场文书
小学大队长竞选稿
2015/11/20 职场文书
工作建议书范文
2019/07/08 职场文书
2019奶茶店创业计划书范本,值得你借鉴
2019/08/14 职场文书
nginx location优先级的深入讲解
2021/03/31 Servers