uWSGI基本上是python做web服务的不二选择了,但似乎项目的开发者比较热衷于其新功能开发,对其使用文档还是相当缺乏的。
安装:
Ubuntu
添加ppa,安装。 目前只有Lucid, Maverick, Natty几个版本还需要添加,以后版本都在官方原,直接apt-get install
即可。
1 2 3 |
add-apt-repository ppa:uwsgi/release apt-get update apt-get install uwsgi-python |
Debian
目前Debian sid已经收录了uwsgi,一般服务器安装的testing/stable,只能自己修改apt的配置,从sid里面port过来。
注意:以下操作可能毁掉您的整个debian包系统。以下命令仅在Debian wheezy,即目前的testing运行测试安装过,如果你的是squeeze,自己修改01all那里 Pin: release a=squeeze
一行,但不保证能够正常运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
echo "deb http://ftp.tw.debian.org/debian sid main non-free contrib" >> /etc/apt/sources.list cat > /etc/apt/preferences.d/01all << EOF Package: * Pin: release a=testing Pin-Priority: 1000 EOF cat > /etc/apt/preferences.d/02uwsgi << EOF Package: uwsgi Pin: release a=sid Pin-Priority: 1010 EOF apt-get update apt-get install uwsgi uwsgi-core uwsgi-plugin-python |
Centos, RHEL, Fedora, …
You’re on your own, linux user.
配置
常见配置文件:
1 2 3 4 5 6 7 8 9 10 11 |
cat > /etc/uwsgi/apps-enabled/test.ini << EOF [uwsgi] chmod-socket = 666 limit-as = 256 processes = 6 max-request = 2000 memory-report = true enable-threads = true virtualenv = /somewhere/to/your/virtualenv wsgi-file = /home/somewhere/app.py EOF |
用ini方式的配置是比xml的容易写多了。具体配置说明请看Doc
默认的sock文件在/var/run/uwsgi/test/socket
配合nginx使用的配置文件:
1 2 3 4 5 6 7 8 9 10 |
cat > /etc/nginx/sites-enabled/test << EOF server { listen 80; server_name host.domain.com; location / { include uwsgi_params; uwsgi_pass unix:///var/run/uwsgi/test/socket; } } EOF |
切换Python版本
系统中可能安装有多个版本的Python,又或者同个系统里面有的app跑python3, 有的跑python2.6 stackless, 有的跑python2.7…
uwsgi 是通过plugin的方式加载不同的python解析器的,debian的uwsgi-plugin-python包里面提供了python26_plugin.so, python27_plugin.so, 不过uwsgi如果在app配置里面没有plugins
参数指定使用哪个时候,会尝试加载/usr/lib/uwsgi/plugins/python_plugin.so
,这个文件在debian下是个链接文件,可以运行update-alternatives --config uwsgi-plugin-python
命令来修改这个默认版本。
源里面没有提供stackless python的plugin,只能自己编译了,还好非常简单:
/path/to/your/stackless/python uwsgiconfig.py --plugin plugins/stackless
然后把生成的python_stackless.so放到/usr/lib/uwsgi/plugins
就能被uwsgi加载了。
其他plugin的编译基本都这样,看源代码里面的plugins目录。
代码
使用uwsgi运行代码的时候,可以import uwsgi模块,和uwsgi进行一定的交互。
uwsgi 的源代码包当中有个uwsgidecorators.py
,提供了多数的uwsgi接口,描述文档在此。以下是几个典型应用。
自动重载
好一些web框架都有检测修改了源文件就自动重新加载的功能,但是在uwsgi里面这个方法是不好用了。
Django
加入以下代码:
1 2 3 4 5 6 7 8 |
import uwsgi from uwsgidecorators import timer from django.utils import autoreload @timer(3) def change_code_gracefull_reload(sig): if autoreload.code_changed(): uwsgi.reload() |
Bottle
Bottle 的reload是它内置基础web服务器的功能,在uwsgi里面只能自己写代码监控。
想要简单很难做到完美:
1 2 3 4 5 6 7 |
from uwsgidecorators import filemon filemon('/tmp/foo')(uwsgi.reload) filemon('/tmp/foo2')(uwsgi.reload) filemon('/tmp/foo3')(uwsgi.reload) filemon('/tmp/foo4')(uwsgi.reload) filemon('/tmp/foo5')(uwsgi.reload) |
于是这些文件出现修改的时候,就自动reload。其实你可以自己加入调用uwsgi.reload()的响应。
pylons, web.py, cherrypy ..
程序员自己研究去。
threading
原来使用内置线程做的异步程序会发现在uwsgi,里面的线程好像都没启动了、数据库没有连接了……原因是uwsgi加载了代码后,fork出多个子进程,子进程里面的线程如果没有被再度激活,是不工作的。
有两个方法,一是在这个app的配置里面加上:
lazy = true
这样代码会在子进程fork了之后才开始加载。
二是使用uwsgi模块的api,uwsgidecorators 里面有相应的装饰器,这样uwsgi会在fork之后自动调用你要重新启动的线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from uwsgidecorators import postfork @postfork def reconnect_to_db(): myfoodb.connect() @postfork def restart_threads(): global thread1, thread2 thread1 = MyThread1() thread1.start() thread2 = MyThread2() thread2.start() |
监控
虽然uwsgi 默认带了SNMP功能,可以给外部监控其运行情况,但uwsgi的源码包里面带了个uwsgistatus.py
文件,里面简单的提供了读取uwsgi模块的属性形成的报告。 可以把里面的代码copy到app项目里面,作为一个简单的监控数据。
转载请注明:爱开源 » uWSGI的几个使用技巧