ichuan.net

自信打不死的心态活到老

用uWSGI替代fastcgi部署django应用

今日有同事推荐我用 uWSGI 来部署 django 应用,因为它比 fastcgi 方式快很多。刚才实验完毕,现在这个blog和 911.im 已经使用上 uWSGI 了。

对比测试

我用的 webbench 来测试 fastcgi 和 uwsgi 两种方式的效率,下面是换 uwsgi 之前的数据:

$ webbench -c 500 -t 30 http://ichuan.net/archives/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

Benchmarking: GET http://ichuan.net/archives/
500 clients, running 30 sec.

Speed=12220 pages/min, 1245829 bytes/sec.
Requests: 6110 susceed, 0 failed.

换 uwsgi 后:

$ webbench -c 500 -t 30 http://ichuan.net/archives/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

Benchmarking: GET http://ichuan.net/archives/
500 clients, running 30 sec.

Speed=42470 pages/min, 2778475 bytes/sec.
Requests: 21235 susceed, 0 failed.

可以看到换 uwsgi 后能处理的页面数是换之前的 3.5 倍左右。这个数据在我本地虚拟机上是 30 倍。

部署过程

首先下载编译 uwsgi:http://projects.unbit.it/downloads/uwsgi-0.9.9.1.tar.gz,我是 ubuntu 系统,需要额外装个 libxml2-dev 库:sudo apt-get install libxml2-dev

编译完后将得到的 uwsgi 复制到系统目录:sudo cp uwsgi /usr/sbin/

启动 uwsgi:

uwsgi -s /tmp/uwsgi.sock -C -M -p 4 -t 30 --limit-as 128 -R 10000 --vhost -d /tmp/uwsgi.log --pidfile /tmp/uwsgi.pid --pythonpath /var/www

表示用 unix socket 方式执行 uwsgi,-C 表示将 /tmp/uwsgi.sock 文件权限改成 666 以便 nginx 可以读取,-M 表示启动管理进程,-p 4 表示预生成 4 个 worker 子进程,-t 30 是 cgi 程序超时,--limit-as 128 表示限制内存最大 128M,-R 10000 表示每个 worker 处理的最大请求数,--vhost 表示启用虚拟服务器,-d /tmp/uwsgi.log 表示以守护进程方式启动,指定日志文件。

这个命令可以放入 /etc/rc.local 作为开机自启动。

这样启动的 uwsgi 可以被多网站共用,nginx 的 server 块配置如下:

location / {
    uwsgi_pass  unix:///tmp/uwsgi.sock;
    uwsgi_param UWSGI_CHDIR  /var/www/djblog;
    uwsgi_param UWSGI_SCRIPT wsgi_app;
    include     uwsgi_params;
}

上面的配置的前提是,你的 django 工程在 /var/www/djblog,并且在该目录下有个 wsgi_app.py 文件。文件内容如下:

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'djblog.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

如此配置好后,重启 nginx 就可以了。

如果要多加一个网站,只需在 nginx 配置中新加个 server 块,改变下 UWSGI_CHDIR 配置即可。

如果要让 uwsgi 重新载入,可以执行:

kill -SIGHUP `cat /tmp/uwsgi.pid`

如果要让停止 uwsgi,可以给它的 master 进程发送 SIGINT 信号:

kill -SIGINT `cat /tmp/uwsgi.pid`

uwsgi 的更多配置在此

Comments