使用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文件右键找不到IDLE打开项解决办法
Jun 08 Python
简单了解Django模板的使用
Dec 20 Python
python实现统计文本中单词出现的频率详解
May 20 Python
python命令行工具Click快速掌握
Jul 04 Python
pytorch sampler对数据进行采样的实现
Dec 31 Python
pytorch实现用CNN和LSTM对文本进行分类方式
Jan 08 Python
Python批量启动多线程代码实例
Feb 18 Python
使用python的turtle函数绘制一个滑稽表情
Feb 28 Python
Jupyter notebook无法导入第三方模块的解决方式
Apr 15 Python
Python pip使用超时问题解决方案
Aug 03 Python
Python利用Pillow(PIL)库实现验证码图片的全过程
Oct 04 Python
如何在python中实现ECDSA你知道吗
Nov 23 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
ADODB类使用
2006/11/25 PHP
使用PHPMailer实现邮件发送代码分享
2014/10/23 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
关于PHP定时发送服务的解决办法
2017/04/23 PHP
PHP基于自定义类随机生成姓名的方法示例
2017/08/05 PHP
PHP删除字符串中非字母数字字符方法总结
2019/01/20 PHP
JavaScript使用cookie
2007/02/02 Javascript
JS实现左右拖动改变内容显示区域大小的方法
2015/10/13 Javascript
超详细的JS弹出窗口代码大全
2020/04/18 Javascript
获取JavaScript异步函数的返回值
2016/12/21 Javascript
Node.js的进程管理的深入理解
2019/01/09 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
2019/04/25 Javascript
新手简单了解vue
2019/05/29 Javascript
手把手带你入门微信小程序新框架Kbone的使用
2020/02/25 Javascript
JavaScript实现弹出窗口效果
2020/12/09 Javascript
在Python中实现贪婪排名算法的教程
2015/04/17 Python
Python获取系统默认字符编码的方法
2015/06/04 Python
教你用Type Hint提高Python程序开发效率
2016/08/08 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
2018/09/04 Python
Python 2/3下处理cjk编码的zip文件的方法
2019/04/26 Python
python将类似json的数据存储到MySQL中的实例
2019/07/12 Python
python opencv调用笔记本摄像头
2019/08/28 Python
Python基础之函数基本用法与进阶详解
2020/01/02 Python
Python脚本去除文件的只读性操作
2020/03/05 Python
浅谈css3新单位vw、vh、vmin、vmax的使用详解
2017/12/01 HTML / CSS
精彩的广告词
2014/03/19 职场文书
关于读书的演讲稿500字
2014/08/27 职场文书
机械专业毕业生自我鉴定2014
2014/10/04 职场文书
商业门面租房协议书
2014/11/25 职场文书
初三英语教学反思
2016/02/15 职场文书
《狼王梦》读后感:可怜天下父母心
2019/11/01 职场文书
基于MySql验证的vsftpd虚拟用户
2021/11/07 MySQL
Redis+Lua脚本实现计数器接口防刷功能(升级版)
2022/02/12 Redis
Win10 Anaconda安装python-pcl
2022/04/29 Servers