django开发环境部署(四)

善,总是以蜗牛的速度前进。然而无论多么艰难,我们始终不该放弃内心深处对善良的追求。

python 自带的轻量级的 web 服务器只能是用来本地测试,到了生产环境必须使用更为强大的 web 服务器,这里我使用的是 nginx,那么 python 应用要和 nginx 进行交互就必须利用一个桥梁和 nginx 通信,这里截取 51CTO 开发频道 python 应用部署部分内容,python 的应用部署比php略显麻烦,

常见的部署方法有:

  • fcgi:用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http服务通信
  • wsgi:利用http服务的mod_wsgi模块来跑各个project。

无论哪种都很麻烦,apache的mod_wsgi配置起来很麻烦,内存占用还大,如果要加上nginx作为静态页面的服务器那就更麻烦了;我的应用基本上到后来都是是各个project各自为战,且不说管理上的混乱,这样对负载也是不利的,空闲的project和繁忙的project同样需要占用内存。

一、uwsgi

这里开始真的混乱了好久,一直没分清uwsgi,uWSGI

  • 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服务器与应用服务器通信的一种规范

  • 关于WSGI看这里:WSGI

  • 关于uwsgi看这里:uwsgi

  • uWSGI:是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换

  • uwsgi:于WSGI一样是一种通信协议,而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。

  • uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型,每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

2.uwsgi据说改进性能之后大约是fcgi协议的10倍那么快,有个比较见下图:

#django的安装前几篇文章也有,这里再centos下安装pip也很简单,uwsgi也可以通过pip来安装 
yum -y install libevent-devel python-devel 
yum -y install python-pip pip install uwsgi 

#测试uwsgi是否能独立启动 
#本地创建一个test.py文件,内容如下 
def application(env, start_response): 
 start_response('200 OK', [('Content-Type','text/html')]) 
 return "Hello World" 

#独立启动uwsgi,测试是否可以成功 
uwsgi --http :8001 --wsgi-file test.py 
 \\这条命令打开了本地8001端口进行监听,http访问即可看到Hello World,表明独立启动uwsgi成功 

2.uWSGI的主要特点如下:

  • 超快的性能
  • 低内存占用(实测为apache2的mod_wsgi的一半左右)
  • 多app管理
  • 详尽的日志功能(可以用来分析app性能和瓶颈)
  • 高度可定制(内存大小限制,服务一定次数后重启等)

部署环境中nginx作为前端响应web请求和处理静态请求,其余非静态请求通过uwsgi传递给django。安装参考了Django中国社区的这篇文章

二、uwsgi + nginx + django

2.1 系统环境

Distribution : CentOS 6.5 minimal 
uwsgi version : 2.0.4
Python version : 2.7
Web Server : Nginx 1.6
Init system : sysvinit

2.2 安装uwsgi,测试uwsgi

django 的安装前几篇文章也有,这里再 centos 下安装 pip 也很简单,uwsgi 也可以通过 pip 来安装

yum -y install libevent-devel python-devel libxml2-devel
yum -y install python-pip
pip install uwsgi


#测试uwsgi是否能独立启动
#本地创建一个test.py文件,内容如下
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return "Hello World"

#独立启动uwsgi,测试是否可以成功
uwsgi --http :8001 --wsgi-file test.py
\\这条命令打开了本地8001端口进行监听,http访问即可看到Hello World,表明独立启动uwsgi成功

2.3 配置 django 连接 uwsgi

1.新建一个 django project,runserver 测试正常启动即可,然后确定关闭django程序关闭

# tree testpro/ -L 1 #注意这里的层级结构
testpro/
├── django_socket.xml
├── django_wsgi.py
├── manage.py
└── testpro #目录

1 directory, 3 files

2.新建 uwsgi 配置文件

这里要注意,python 2.7版本,如果是 python 2.6,则会报错

#!/usr/bin/env python 
# coding: utf-8
import os
import sys
# 将系统的编码设置为UTF8
reload(sys)
sys.setdefaultencoding('utf8')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tryfirst.settings")

from django.core.handlers.wsgi
import WSGIHandler application = WSGIHandler()


#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testpro.settings")
#import django.core.handlers.wsgi
#application = django.core.handlers.wsgi.WSGIHandler()

2.这时候利用 uwsgi 启动服务,访问 8000 端口是否能看到 django 应用的界面

uwsgi --http :8000 --chdir /home/src/sites/mysite --module django_wsgi.py

注意 chdir 路径是我本地的 django 项目测试地址

到了这里成功的话利用 uwsgi 单独启动 django 应用就没有问题了,下一步让uwsgi 和 nginx 实现通信,作为桥梁,就可以实现我们的目的了

2.4 uwsgi 的一些参数和调优建议

详细介绍请查看参考阅读 uwsgi

#并发四个线程 
uwsgi -s :9090 -w mysite -p 4

#主控线程+4个线程
uwsgi -s :9090 -w mysite -M -p 4

#执行超过30s的client直接放弃
uwsgi -s :9090 -w mysite -M -p 4 -t 30

#限制内存空间
uwsgi -s :9090 -w mysite -M -p 4 -t 30 --limit-as 128

#服务超过10000个request自动respawn
uwsgi -s :9090 -w mysite -M -p 4 -t 30 --limit-as 128 -R 10000

#后台运行
uwsgi -s :9090 -w mysite -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log

2.5 配置 uwsgi 连接 nginx

安装 nginx,这里略,上面是通过命令行启动 uwsgi,线上肯定是使用配置文件。我们让 nginx 和 uwsgi 通信使用 socket 来进行通讯,所以注意使用的通信端口没有被其他程序占用即可

1、新建 django_socket.xml,内容如下

<uwsgi> 
<socket>:8000</socket>
<chdir>/home/src/sites/mysite/</chdir>
<module>django_wsgi</module>
<processes>4</processes> <!-- 进程数 -->
<daemonize>uwsgi.log</daemonize>
</uwsgi>

2、nginx核心配置如下

server {

listen 80;
server_name 192.168.122.136;
access_log /home/ms/mysite/access.log;
error_log /home/ms/mysite/error.log;

location / {
include uwsgi_params; #这个模块编译好
uwsgi_pass 127.0.0.1:8000;
}

#error_page 404 /404.html;

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

# location /static/ {
# alias /home/work/src/sites/testdjango1/testdjango/collectedstatic/;
# index index.html index.htm;
# }

# location /media/ {
# alias /home/work/src/sites/testdjango1/testdjango/public/media/;
# }
}

3、启动 nginx,以配置文件方式启动 uwsgi,检查端口和进程是否能正常

nginx -s reload 
uwsgi -x /home/src/sites/mysite/django_socket.xml

全部正常之后就可以尝试访问 nginx 的域名 80 端口进行访问,看是否能看到django 运行的页面了,查看日志,也能看到 uwsgi 接受到了请求

三、uwsgi 的启动关闭脚本

这部分是可选的,但是一旦投入线上使用,每次都使用命令行很显然是不切实际的,所以编写成类似于独立启动的服务脚本,方便启动和关闭 uwsgi,稍后补上

稍后补上

参考阅读