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 的更多配置在此

nginx 配置技巧

这段时间因为折腾 VPS,学习了下 nginx 的配置。下面分享一些我觉得有用的配置,更多的配置参见 nginx 配置手册

不让以 IP 形式访问

一个 IP 下可能同时挂了好多站,别人直接用 IP 访问不定会访问到哪个站,还容易被人发现这个 IP 下挂了某些站。下面这个配置就是让用 IP 访问的人重定向到一个错误页面(下面是 google 404 页面):

server {
    listen 80 default_server;
    add_header Location http://www.google.com/404.html;
    return 301;
}

上例中 default_server 指的是如果没有找到对应域名的网站时用这个配置,用 IP 访问就属于这一种了。

让 www 域名跳转到主站

域名贵在短小,加上 www 访问简直就像乔布斯费尽心思降低 0.5mm 厚度的 iPhone 到中国后被贴上个 5mm 的屏幕膜一样。下面例子是如果访问 http://www.ichuan.net/a/b 会被重定向到 http://ichuan.net/a/b

if ($host = 'www.ichuan.net'){
    rewrite  ^/(.*)$  http://ichuan.net/$1  permanent;
}

媒体文件加缓存头

这个是从 nginx 官网找的代码,很方便:

if ($request_filename ~* \.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov)$){
    access_log   off;
    expires      30d;
}

意思是对这些后缀的文件,不记录访问日志,并让浏览器缓存 30 天。

aliasroot 的区别

这个一般用在 location 字段。假如是 location ^~ /static/ ,浏览器请求 /static/css/screen.css 时,如果你 location 里面写的是 alias /var/www/static/;,则 nginx 会去找 /var/www/static/css/screen.css 文件发给浏览器;但如果你写的是 root /var/www/static/;,nginx 则会去找 /var/www/static/static/css/screen.css 文件,也就是说 root 找文件时是不会忽略 location 后面的路径的。

先列这几个,以后有新的了再更新。