好了,debian官方的uwsgi总算出来了。包已经到了testing,stable暂时别指望了,等下一次release吧。这次打的包,比贝壳打的复杂多了。贝壳自己只打了python专用的包,debian官方的包将多个语言分别打成了plugins。
<uwsgi>
好了,debian官方的uwsgi总算出来了。包已经到了testing,stable暂时别指望了,等下一次release吧。这次打的包,比贝壳打的复杂多了。贝壳自己只打了python专用的包,debian官方的包将多个语言分别打成了plugins。
<uwsgi>
wsgi是python的一个标准web服务接口,具体去google pep文档,不解释。在李木头的忽悠下,贝壳试用了一下uwsgi搭建python服务器,感觉还不错。
首先,贝壳将uwsgi打包成deb包,因为这东西和python基本没什么关系,就是一个标准的系统守护服务程序。其中贝壳测试了一下,uwsgi编译的时候是依赖版本的。所以请教了一下thomas,打了uwsgi2.6和uwsgi2.7两个包。没办法,mercurial对python2.7的支持不是很好,每次都出问题。具体的可以加贝壳的repos: http://shell909090.com/debian/ testing,然后通过一下贝壳的key,就可以直接安装uwsgi2.6了。当然,不通过key也可以,只是每次安装升级都有警告。
贝壳写了一个很简单的init.d,使用–vhost来启动uwsgi为服务模式。这种模式的好处是,uwsgi的具体执行的应用都是由nginx来确定的,因此所有的映射只需要修改nginx配置就好。uwsgi参数很多,包括可以指定内存限制,工作进程/线程,定时重启工作进程,多解释器等等。是一个高效的,功能强大的服务器。具体可以自己参考调整。最好的的地方是,uwsgi还支持virtualenv,你可以给不同的应用建立不同的工作环境,从而在环境中使用指定的包,而不是系统包。
下面是一个nginx配置的例子。
location /ticket {
include uwsgi_params;
uwsgi_param UWSGI_PYHOME /usr;
uwsgi_param UWSGI_CHDIR /home/shell/workspace/hg/thost;
uwsgi_param UWSGI_SCRIPT main;
uwsgi_pass unix:/var/run/uwsgi.socket;
}
location /mlocate {
include uwsgi_params;
uwsgi_param UWSGI_PYHOME /usr;
uwsgi_param UWSGI_CHDIR /home/shell/workspace/hg/thost;
uwsgi_param UWSGI_SCRIPT main;
uwsgi_pass unix:/var/run/uwsgi.socket;
}
location /hg {
include uwsgi_params;
uwsgi_param UWSGI_PYHOME /usr;
uwsgi_param UWSGI_CHDIR /home/shell/workspace/hg;
uwsgi_param UWSGI_SCRIPT hgweb;
uwsgi_param SCRIPT_NAME /;
uwsgi_param SERVER_NAME hgweb;
uwsgi_pass unix:/var/run/uwsgi.socket;
}
这里面设定了三个应用。由于贝壳不需要virtualenv,所以PYHOME设定了/usr。第一二个应用的基础路径在/home/shell/workspace/hg/thost,脚本叫做main.py。第三个应用的基础路径在/home/shell/workspace/hg,脚本叫做hgweb.py。需要注意的是,uwsgi会以模块方式导入这些脚本,然后使用其中的application对象作为wsgi处理函数。所以不要把application对象赋值放在if __name__ == ‘__main__’里面,那没用的。第三个应用指定了SCRIPT_NAME和SERVER_NAME,是因为hg的wsgi模块没有SCRIPT_NAME不工作,而这个应用和前两个不在一起,所以如果不指定SERVER_NAME会导致覆盖冲突。
这种部署模式的好处是,我可以使用一个宿主来管理所有的应用,而不必每个应用启动一个宿主,省去了多个宿主管理的麻烦。而多进程,压力分布等等问题都被uwsgi的配置系统搞定了。于是应用程序宿主做到了彻底的免管理,即装即用,只用调节性能匹配即可。具体程序配置下放到nginx中,要修改映射关系只用管理一个位置。
我假定你了解hg,了解python,理解nginx或者其他cgi/fcgi的配置过程。现在想用http发布自己的mercurial仓库,而且可能发布一群,怎么操作呢?
本文系电脑资料,同步到blog上。小黄姐姐不必看了,可以帮我留个言。
nginx性能不错,可惜不支持WebDAV,因此没法拿来作为subversion的http服务。于是考虑开一个nginx作为前端,后端就跑一个apache来作为容器。配置这么写的(节选):
=========/etc/nginx/sites-enabled/default=========
server {
listen 443;
server_name OOXX
ssl on;
ssl_certificate keys/server.crt;
ssl_certificate_key keys/server.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/localhost.access.log;
include /etc/nginx/mapping-ssl;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/nginx-default;
}
}
========================================
打开了一个https的服务,这是当然的,svn传输的数据使用http很危险。
===========/etc/nginx/mapping-ssl=============
location ^~ /svn {
proxy_set_header Destination $http_destination;
proxy_pass http://apache_svr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
========================================
将/svn下面的所有请求交给apache2。
=====/etc/apache2/mods-enabled/dav_svn.conf=====
<Location /svn/main>
DAV svn
SVNPath /var/web/svn/main
AuthType Basic
AuthName “Subversion Repository”
Require valid-user
AuthUserFile /var/web/svn/main/conf/passwd
AuthzSVNAccessFile /var/web/svn/main/conf/authz
</Location>
========================================
看起来很美,但是在使用中会发生502错误,原因是来自文件移动后,svn会使用COPY作为Verb去请求服务器端,这时候发生了这样一条日志:
==========/var/log/apache2/access.log==========
127.0.0.1 – {user} [02/Apr/2010:11:07:31 +0800] “COPY {path} HTTP/1.0″ 502 546 “-” “SVN/1.5.4 (r33841)/TortoiseSVN-1.5.5.14361 neon/0.28.3″
========================================
搜索了一下,这是因为使用https作为http服务的前端造成的,这里(https://secure.bonkabonka.com/blog/2008/01/04/nginx_fronting_for_subversion.html)提到了解决方案,而它又引用了另一个网页(http://silmor.de/49)解释细节。不幸的是,这个细节是错误的。关键在于这句上
LoadModule headers_module /usr/lib/apache2/modules/mod_headers_too.so
仔细看一下就会发现,mod_headers_too应当是mod_headers。在debian下,应当执行这几条指令。
cd /etc/apache2/mods-enabled
ln -s ../mods-available/headers.load headers.load
然后,在/etc/apache2/httpd.conf中写入以下内容:
RequestHeader edit Destination ^https http early
问题解决,Q.E.D。