使用Nginx+uWsgi实现Python的Django框架站点动静分离
由于:
Django处理静态文件不太友好;
以后有可能需要处理php或者其他资源的请求;
所以考虑结合nginx,使用nignx做它擅长的路由分发功能;同时做动静分离,即Http请求统一由Nginx进行分发,静态文件由Nginx处理,并返回给客户端;而动态的请求,则分发到uWsgi,由uWsgi再分发给Django进行处理。即客户端<->nginx<->socket<->uwsgi<->Django
一、环境
系统:centOS6
- python:2.7(注意:Django要在2.7版本或以上的python来)
- nginx
- uswgi
所以,安装前,先在控制台输入python—version查看当前python的默认版本,如果在2.7以下,则修改默认版本。(详见附录)
二、安装nginx、uWsgi
安装
nginxsudoyuminstallnginx
安装
pipsudoyuminstallpython-pip
安装
uWsgisudopipuwsgi
三、测试nginx、uWsgi
1.测试nginx启动测试nginx,看是否安装成功启动sudoservicenginxstart然后在浏览器中,输入ip地址,看是否出现nginx的欢迎页面,出现则说明安装成功
2.测试uWsgi在服务器上做任意目录下(一般在home下的某一目录),新建test.py,如下:
#test.pydef application(env,start_response): start_response('200OK',[('Content-Type','text/html')]) return"HelloWorld"
启动以Http方式访问的uWsgi,在test.py同一目录下,输入如下命令行(8001是监听的端口,可以改成你想要的端口)
uwsgi--http:8001--wsgi-filetest.py
然后在浏览器中,输入ip地址:8001,看是否响应helloworld,是则说明安装成功
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-filetest.py
--http:8001--wsgi-filetest.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内容如下:
""" WSGIconfigforWHPAIWechatproject. ItexposestheWSGIcallableasamodule-levelvariablenamed``application``. Formoreinformationonthisfile,seehttps://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ """ importosfromdjango.core.wsgiimport get_wsgi_applicationos.environ.setdefault("DJANGO_SETTINGS_MODULE","WHPAIWechat.settings") application=get_wsgi_application()
启动以Http方式访问uWsgiuwsgi--http:8000--chdir/home/jiayandev/WHPAIWechat/--wsgi-fileWHPAIWechat/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处理
更多规则可以视业务情况而定,完整的配置如下:
upstreamdjango{ server127.0.0.1:8000;#注意8000是上述uwsgi监听的端口 } server{ listen80default_server; server_name_; #charsetkoi8-r; #access_loglogs/host.access.logmain; #Loadconfigurationfilesforthedefaultserverblock. include/etc/nginx/default.d/*.conf; location=/404.html{ root/usr/share/nginx/html; } #redirectservererrorpagestothestaticpage/50x.html # error_page500502503504/50x.html; location=/50x.html{ root/usr/share/nginx/html; } location~\.html${ root/usr/share/nginx/html/front; indexindex.htmlindex.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_passdjango; } *#PHP分到9000端口** # #location~\.php${ #roothtml; #fastcgi_pass127.0.0.1:9000; #fastcgi_indexindex.php; #fastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name; #includefastcgi_params; #}* }
同时,uswgi_param内容如下,照抄即可
uwsgi_paramQUERY_STRING$query_string; uwsgi_paramREQUEST_METHOD$request_method; uwsgi_paramCONTENT_TYPE$content_type; uwsgi_paramCONTENT_LENGTH$content_length; uwsgi_paramREQUEST_URI$request_uri; uwsgi_paramPATH_INFO$document_uri; uwsgi_paramDOCUMENT_ROOT$document_root; uwsgi_paramSERVER_PROTOCOL$server_protocol; uwsgi_paramREMOTE_ADDR$remote_addr; uwsgi_paramREMOTE_PORT$remote_port; uwsgi_paramSERVER_PORT$server_port; uwsgi_paramSERVER_NAME$server_name;
配置完成后,重启或者reloadnginx配置即可生效
重启:
sudoservicenginxrestart
reload:
sudoservicenginxreload
然后直接访问,看看有什么不一样:
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命令变成uwsgiWHPAIWechat_uwsgi.ini