<h2 style="-webkit-print-color-adjust: exact; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #cccccc; font-family: Helvetica, arial, sans-serif; margin-top: 0px !important;">django开发环境部署(四)——uwsgi,nginx</h2> <ol style="-webkit-print-color-adjust: exact; margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">python自带的轻量级的web服务器只能是用来本地测试,到了生产环境必须使用更为强大的web服务器,这里我使用的是nginx,那么python应用要和nginx进行交互就必须利用一个桥梁和nginx通信,这里截取<a style="-webkit-print-color-adjust: exact; color: #4183c4; margin-top: 0px;" href="http://developer.51cto.com/art/201010/229615.htm">51CTO开发频道python应用部署</a>部分内容,python的应用部署比php略显麻烦,</p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">常见的部署方法有:<br style="-webkit-print-color-adjust: exact; margin-top: 0px;" />fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务通信<br style="-webkit-print-color-adjust: exact;" />wsgi:利用http服务的mod_wsgi模块来跑各个project。</p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">无论哪种都很麻烦,apache的mod_wsgi配置起来很麻烦,内存占用还大,如果要加上nginx作为静态页面的服务器那就更麻烦了;我的应用基本上到后来都是是各个project各自为战,且不说管理上的混乱,这样对负载也是不利的,空闲的project和繁忙的project同样需要占用内存。</p> </li> </ol> <h2 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #cccccc; font-family: Helvetica, arial, sans-serif;">uwsgi介绍</h2> <blockquote style="-webkit-print-color-adjust: exact; margin: 15px 0px; border-left-color: #dddddd; padding: 0px 15px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px;">这里开始真的混乱了好久,一直没分清uwsgi,uWSGI</p> </blockquote> <ul style="-webkit-print-color-adjust: exact; margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">WSGI is the Web Server Gateway Interface. It is a specification for web servers and application servers to communicate with web applications (though it can also be used for more than that),翻译过来大致是:WSGI是一种Web服务器网关接口。它是一个Web服务器与应用服务器通信的一种规范</p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">关于WSGI看这里:<a style="-webkit-print-color-adjust: exact; color: #4183c4; margin-top: 0px;" href="http://wsgi.readthedocs.org/en/latest/">WSGI</a></p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">关于uwsgi看这里:<a style="-webkit-print-color-adjust: exact; color: #4183c4; margin-top: 0px;" href="http://uwsgi-docs.readthedocs.org/en/latest/Protocol.html">uwsgi</a></p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">uWSGI:是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换</p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">uwsgi:于WSGI一样是一种通信协议,而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。</p> </li> <li style="-webkit-print-color-adjust: exact; margin: 0px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px 0px 15px;">uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型,每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。</p> </li> </ul> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">2.uwsgi据说改进性能之后大约是fcgi协议的10倍那么快,有个比较见下图:</p> <p> </p> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"><img title="NewImage.png" src="http://static.oschina.net/uploads/img/201405/15124004_46O5.png" alt="NewImage" width="600" height="537" border="0" /></p> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">2.uWSGI的主要特点如下:</p> <ul style="-webkit-print-color-adjust: exact; margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <li style="-webkit-print-color-adjust: exact; margin: 0px;">超快的性能</li> <li style="-webkit-print-color-adjust: exact; margin: 0px;">低内存占用(实测为apache2的mod_wsgi的一半左右)</li> <li style="-webkit-print-color-adjust: exact; margin: 0px;">多app管理</li> <li style="-webkit-print-color-adjust: exact; margin: 0px;">详尽的日志功能(可以用来分析app性能和瓶颈)</li> <li style="-webkit-print-color-adjust: exact; margin: 0px;">高度可定制(内存大小限制,服务一定次数后重启等)</li> </ul> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">部署环境中nginx作为前端响应web请求和处理静态请求,其余非静态请求通过uwsgi传递给django。安装参考了<a style="-webkit-print-color-adjust: exact; color: #4183c4;" href="http://django-china.cn/topic/101/#top">Django中国社区的这篇文章</a></p> <h2 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #cccccc; font-family: Helvetica, arial, sans-serif;">uwsgi+nginx+django</h2> <h4 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif;">系统环境</h4> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Distribution : CentOS 6.5 minimal <br />uwsgi version : 2.0.4 <br />Python version : 2.7<br />Web Server : Nginx 1.6 <br />Init system : sysvinit </code></pre> <h4 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif;">安装步骤</h4> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">- 安装系统(略) <br />- pip、django <br />- 安装uwsgi、测试uwsgi <br />- 配置django连接uwsgi <br />- 配置uwsgi,nginx <br />- 实现nginx + uwsgi + django </code></pre> <h3 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif;">step1:安装uwsgi,测试uwsgi</h3> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">#django的安装前几篇文章也有,这里再centos下安装pip也很简单,uwsgi也可以通过pip来安装 <br />yum -y install libevent-devel python-devel <br />yum -y install python-pip pip install uwsgi <br /><br />#测试uwsgi是否能独立启动 <br />#本地创建一个test.py文件,内容如下 <br />def application(env, start_response): <br /> start_response('200 OK', [('Content-Type','text/html')]) <br /> return "Hello World" <br /><br />#独立启动uwsgi,测试是否可以成功 <br />uwsgi --http :8001 --wsgi-file test.py <br /> \\这条命令打开了本地8001端口进行监听,http访问即可看到Hello World,表明独立启动uwsgi成功 </code></pre> <h4 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif;">step2:配置django连接uwsgi</h4> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">1.新建一个django project,runserver测试正常启动即可,然后确定关闭django程序关闭</p> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">2.新建uwsgi配置文件</p> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">#!/usr/bin/env python <br /># coding: utf-8 <br />import os <br />import sys <br /># 将系统的编码设置为UTF8 <br />reload(sys) <br />sys.setdefaultencoding('utf8') <br />os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tryfirst.settings") <br /><br />from django.core.handlers.wsgi <br />import WSGIHandler application = WSGIHandler() </code></pre> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">2.#这时候利用uwsgi启动服务,访问8000端口是否能看到django应用的界面</p> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">uwsgi —http :8000 —chdir /home/src/sites/mysite —module django_wsgi <br /> \\注意chdir路径是我本地的django项目测试地址 </code></pre> <blockquote style="-webkit-print-color-adjust: exact; margin: 15px 0px; border-left-color: #dddddd; padding: 0px 15px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px;">到了这里成功的话利用uwsgi单独启动django应用就没有问题了,下一步让uwsgi和nginx实现通信,作为桥梁,就可以实现我们的目的了</p> </blockquote> <h2 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 24px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #cccccc; font-family: Helvetica, arial, sans-serif;">step3:uwsgi的一些参数和调优建议</h2> <blockquote style="-webkit-print-color-adjust: exact; margin: 15px 0px; border-left-color: #dddddd; padding: 0px 15px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px;">详细介绍请查看uwsgi文档:http://uwsgi-docs.readthedocs.org/en/latest/Options.html</p> </blockquote> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">#并发四个线程 <br />uwsgi -s :9090 -w mysite -p 4 <br /><br />#主控线程+4个线程 <br />uwsgi -s :9090 -w mysite -M -p 4 <br /><br />#执行超过30s的client直接放弃 <br />uwsgi -s :9090 -w mysite -M -p 4 -t 30 <br /><br />#限制内存空间 <br />uwsgi -s :9090 -w mysite -M -p 4 -t 30 --limit-as 128 <br /><br />#服务超过10000个request自动respawn <br />uwsgi -s :9090 -w mysite -M -p 4 -t 30 --limit-as 128 -R 10000 <br /><br />#后台运行 <br />uwsgi -s :9090 -w mysite -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log </code></pre> <h4 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif;"><br /><br />step4:配置uwsgi连接nginx</h4> <blockquote style="-webkit-print-color-adjust: exact; margin: 15px 0px; border-left-color: #dddddd; padding: 0px 15px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;"> <p style="-webkit-print-color-adjust: exact; margin: 0px;">安装nginx,这里略,上面是通过命令行启动uwsgi,线上肯定是使用配置文件。我们让nginx和uwsgi通信使用socket来进行通讯,所以注意使用的通信端口没有被其他程序占用即可</p> </blockquote> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">1、新建django_socket.xml,内容如下</p> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><uwsgi> <br /><socket>:8000</socket> <br /><chdir>/home/src/sites/mysite/</chdir> <br /><module>django_wsgi</module> <br /><processes>4</processes> <!-- 进程数 --> <br /><daemonize>uwsgi.log</daemonize> <br /></uwsgi> </code></pre> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">2、nginx核心配置如下</p> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">server { <br /> listen 80; <br /> server_name 192.168.122.136; <br /> access_log /home/ms/mysite/access.log; <br /> error_log /home/ms/mysite/error.log; <br /><br /> location / { <br /> include uwsgi_params; #这个模块编译好的位置再/etc/nginx/下 <br /> uwsgi_pass 127.0.0.1:8000; <br /> } <br /><br /> # error_page 404 /404.html; <br /> # redirect server error pages to the static page /50x.html <br /> # error_page 500 502 503 504 /50x.html; <br /><br /> location = /50x.html { <br /> root html; <br /> } <br /><br /> # location /static/ { #这里我只是作为演示我注释掉了静态资源,如果实际部署需要打开,下面同理<br /> # alias /home/work/src/sites/testdjango1/testdjango/collectedstatic/; <br /> # index index.html index.htm; <br /> # } <br /><br /> # location /media/ { <br /> # alias /home/work/src/sites/testdjango1/testdjango/public/media/; <br /> # } <br />}</code></pre> <p style="-webkit-print-color-adjust: exact; margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px;">3、启动nginx,以配置文件方式启动uwsgi,检查端口和进程是否能正常</p> <pre style="-webkit-print-color-adjust: exact; margin: 15px 0px; background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="-webkit-print-color-adjust: exact; margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">nginx -s reload <br />uwsgi -x /home/src/sites/mysite/django_socket.xml <br /> \\全部正常之后就可以尝试访问nginx的域名进行访问,看是否能看到django运行的页面了</code></pre> <h4 style="font-size: 16px; -webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-family: Helvetica, arial, sans-serif;">step5:uwsgi的启动关闭脚本</h4> <h4 style="-webkit-print-color-adjust: exact; margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 16px; font-family: Helvetica, arial, sans-serif;"><span style="color: #777777; font-size: 14px; line-height: 22px;">这部分是可选的,但是一旦投入线上使用,每次都使用命令行很显然是不切实际的,所以编写成类似于独立启动的服务脚本,方便启动和关闭uwsgi</span></h4>