Welcome to jaever.com/diary

[转载]Python: 50个能够满足所有需要的模块

Graphical interface wxPython http://wxpython.org  
Graphical interface pyGtk http://www.pygtk.org  
Graphical interface pyQT http://www.riverbankcomputing.co.uk/pyqt/  
Graphical interface Pmw http://pmw.sourceforge.net/  
Graphical interface Tkinter 3000 http://effbot.org/zone/wck.htm  
Graphical interface Tix http://tix.sourceforge.net/  
       
Database MySQLdb http://sourceforge.net/projects/mysql-python  
Database PyGreSQL http://www.pygresql.org/  
Database Gadfly http://gadfly.sourceforge.net/  
Database SQLAlchemy http://www.sqlalchemy.org/  
Database psycopg http://www.initd.org/pub/software/psycopg/  
Database kinterbasdb http://kinterbasdb.sourceforge.net/  
Database cx_Oracle http://www.cxtools.net/default.aspx?nav=downloads  
Database pySQLite http://initd.org/tracker/pysqlite  
       
MSN Messenger msnlib http://auriga.wearlab.de/~alb/msnlib/  
MSN Messenger pymsn http://telepathy.freedesktop.org/wiki/Pymsn  
MSN Messenger msnp http://msnp.sourceforge.net/  
Network Twisted http://twistedmatrix.com/  
Images PIL http://www.pythonware.com/products/pil/  
Images gdmodule http://newcenturycomputers.net/projects/gdmodule.html  
Images VideoCapture http://videocapture.sourceforge.net/  
       
Sciences and Maths scipy http://www.scipy.org/  
Sciences and Maths NumPy http://numpy.scipy.org//  
Sciences and Maths numarray http://www.stsci.edu/resources/software_hardware/numarray  
Sciences and Maths matplotlib http://matplotlib.sourceforge.net/  
       
Games Pygame http://www.pygame.org/news.html  
Games Pyglet http://www.pyglet.org/  
Games PySoy http://www.pysoy.org/  
Games pyOpenGL http://pyopengl.sourceforge.net/  
       
Jabber jabberpy http://jabberpy.sourceforge.net/  
       
Web scrape http://zesty.ca/python/scrape.html  
Web Beautiful Soup http://crummy.com/software/BeautifulSoup  
Web pythonweb http://www.pythonweb.org/  
Web mechanize http://wwwsearch.sourceforge.net/mechanize/  
       
Localisation geoname.py http://www.zindep.com/blog-zindep/Geoname-python/  
       
Serial port pySerial http://pyserial.sourceforge.net/  
Serial port USPP http://ibarona.googlepages.com/uspp  
       
Parallel Port pyParallel http://pyserial.sourceforge.net/pyparallel.html  
       
USB Port pyUSB http://bleyer.org/pyusb/  
       
Windows ctypes http://starship.python.net/crew/theller/ctypes/  
Windows pywin32 http://sourceforge.net/projects/pywin32/  
Windows pywinauto http://www.openqa.org/pywinauto/  
Windows pyrtf http://pyrtf.sourceforge.net/  
Windows wmi http://timgolden.me.uk/python/wmi.html  
       
PDA/GSM/Mobiles pymo http://www.awaretek.com/pymo.html  
PDA/GSM/Mobiles pyS60 http://sourceforge.net/projects/pys60  
       
Sound pySoundic http://pysonic.sourceforge.net/  
Sound pyMedia http://pymedia.org/  
Sound FMOD http://www.fmod.org/  
Sound pyMIDI http://www.cs.unc.edu/Research/assist/developer.shtml  
       
GMail libgmail http://libgmail.sourceforge.net/  
Google pyGoogle http://pygoogle.sourceforge.net/  
Expect pyExpect http://pexpect.sourceforge.net/  
WordNet pyWordNet http://osteele.com/projects/pywordnet/  
Command line cmd http://blog.doughellmann.com/2008/05/pymotw-cmd.html  
Compiler backend llvm-py http://mdevan.nfshost.com/llvm-py/  
3D VPython http://vpython.org
CONTINUE
INFO: 2008-09-09 09:32:44 | purpen | digg | link

(转载)深度优先搜索和广度优先搜索

一、深度优先搜索 
    深度优先搜索就是在搜索树的每一层始终先只扩展一个子节点,不断地向纵深前进直到不能再前进(到达叶子节点或受到深度限制)时,才从当前节点返回到上一级节点,沿另一方向又继续前进。这种方法的搜索树是从树根开始一枝一枝逐渐形成的。

      深度优先搜索亦称为纵向搜索。由于一个有解的问题树可能含有无穷分枝,深度优先搜索如果误入无穷分枝(即深度无限),则不可能找到目标节点。所以,深度优先搜索策略是不完备的。另外,应用此策略得到的解不一定是最佳解(最短路径)。

深度优先搜索的路径示意图:

三、广度优先搜索

    在深度优先搜索算法中,是深度越大的结点越先得到扩展。如果在搜索中把算法改为按结点的层次进行搜索, 本层的结点没有搜索处理完时,不能对下层结点进行处理,即深度越小的结点越先得到扩展,也就是说先产生 的结点先得以扩展处理,这种搜索算法称为广度优先搜索法。

 

广度优先搜索路径示意图:

CONTINUE
INFO: 2008-09-08 08:29:53 | purpen | digg | link

[转载]网页爬虫汇总

Heritrix
Heritrix是一个开源,可扩展的web爬虫项目。Heritrix设计成严格按照robots.txt文件的排除指示和META robots标签。
http://crawler.archive.org/

WebSPHINX
WebSPHINX是一个Java类包和Web爬虫的交互式开发环境。Web爬虫(也叫作机器人或蜘蛛)是可以自动浏览与处理Web页面的程序。WebSPHINX由两部分组成:爬虫工作平台和WebSPHINX类包。
http://www.cs.cmu.edu/~rcm/websphinx/

WebLech
WebLech是一个功能强大的Web站点下载与镜像工具。它支持按功能需求来下载web站点并能够尽可能模仿标准Web浏览器的行为。WebLech有一个功能控制台并采用多线程操作。
http://weblech.sourceforge.net/

Arale
Arale主要为个人使用而设计,而没有像其它爬虫一样是关注于页面索引。Arale能够下载整个web站点或来自web站点的某些资源。Arale还能够把动态页面映射成静态页面。
http://web.tiscali.it/_flat/arale.jsp.html

J-Spider
J-Spider:是一个完全可配置和定制的Web Spider引擎.你可以利用它来检查网站的错误(内在的服务器错误等),网站内外部链接检查,分析网站的结构(可创建一个网站地图),下载整个Web站点,你还可以写一个JSpider插件来扩展你所需要的功能。
http://j-spider.sourceforge.net/

spindle
spindle 是一个构建在Lucene工具包之上的Web索引/搜索工具.它包括一个用于创建索引的HTTP spider和一个用于搜索这些索引的搜索类。spindle项目提供了一组JSP标签库使得那些基于JSP的站点不需要开发任何Java类就能够增加搜 索功能。
http://www.bitmechanic.com/projects/spindle/

Arachnid
Arachnid: 是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并能够在Web站上的每个页面被解析之后增加几行代码调用。 Arachnid的下载包中包含两个spider应用程序例子用于演示如何使用该框架。
http://arachnid.sourceforge.net/

LARM
LARM能够为Jakarta Lucene搜索引擎框架的用户提供一个纯Java的搜索解决方案。它包含能够为文件,数据库表格建立索引的方法和为Web站点建索引的爬虫
http://larm.sourceforge.net/

JoBo
JoBo 是一个用于下载整个Web站点的简单工具。它本质是一个Web Spider。与其它下载工具相比较它的主要优势是能够自动填充form(如:自动登录)和使用cookies来处理session。JoBo还有灵活的 下载规则(如:通过网页的URL,大小,MIME类型等)来限制下载。
http://www.matuschek.net/software/jobo/index.html

snoics-reptile
snoics -reptile是用纯Java开发的,用来进行网站镜像抓取的工具,可以使用配制文件中提供的URL入口,把这个网站所有的能用浏览器通过GET的方式 获取到的资源全部抓取到本地,包括网页和各种类型的文件,如:图片、flash、mp3、zip、rar、exe等文件。可以将整个网站完整地下传至硬盘 内,并能保持原有的网站结构精确不变。只需要把抓取下来的网站放到web服务器(如:Apache)中,就可以实现完整的网站镜像。
http://www.blogjava.net/snoics

Web-Harvest
Web-Harvest是一个Java开源Web数据抽取工具。它能够收集指定的Web页面并从这些页面中提取有用的数据。Web-Harvest主要是运用了像XSLT,XQuery,正则表达式等这些技术来实现对text/xml的操作。
http://web-harvest.sourceforge.net

spiderpy
spiderpy是一个基于Python编码的一个开源web爬虫工具,允许用户收集文件和搜索网站,并有一个可配置的界面。
http://pyspider.sourceforge.net/

The Spider Web Network Xoops Mod Team
pider Web Network Xoops Mod是一个Xoops下的模块,完全由PHP语言实现。
http://www.tswn.com/

Fetchgals
Fetchgals是一个基于perl多线程的Web爬虫,通过Tags来搜索色情图片。
https://sourceforge.net/projects/fetchgals

larbin
larbin是个基于C++的web爬虫工具,拥有易于操作的界面,不过只能跑在LINUX下,在一台普通PC下larbin每天可以爬5百万个页面(当然啦,需要拥有良好的网络)
http://larbin.sourceforge.net/index-eng.html

CONTINUE
INFO: 2008-09-08 05:39:12 | purpen | digg | link

Google Gears:让你把网页应用延伸到桌面

Google Gears是一个开源产品,它能够在离线情况下使用网页应用程序。它的主要功能包括捕捉并支撑组成网页应用程序的资源和代码,具体包括图片、逻辑和外观;Gears的另外一个主要功能是创建网页应用程序能够访问的本地数据库;第三个功能使得开发人员能够通过多核处理器的多线程能力来在后台运行JavaScript。通过这个功能,开发人员能够创建基于网页的应用程序及其桌面版本,并且这两个版本之间能够进行同步。如果没有多线程功能,那么当一个网页应用程序与本地桌面版的应用程序进行同步时,Gears会先冻结应用程序直到同步完成。

 

同步功能对任何跨两个平台的应用程序来说都是必须具有的功能,但对于用户来说出现任何延迟都是不可接受的。Google开发部经理Brent Taylor表示,希望业内共同努力把这些功能作为所有浏览器的标准。

  而Google并不是唯一一间想把网页应用程序延伸到桌面的公司。

  Adobe的Apollo也针对同样目标设计。然而,Apollo寄生在桌面并且能够访问到任何本地的文件系统,而Gears只能访问到由它创建的轻量级SQL数据库。但是Adobe高级副主席兼首席软件架构师Kevin Lynch表示,Apollo中将会提供Gears的API。

CONTINUE
INFO: 2008-09-08 02:26:55 | purpen | digg | link

Wget非交互式的网络文件下载工具

GNU Wget 1.10.2,非交互式的网络文件下载工具。
用法: wget [选项]... [URL]...

Mandatory arguments to long options are mandatory for short options too.

开始:
 -V,  --version  显示Wget版本之后退出。
 -h,  --help      显示本帮助
 -b,  --background        启动后转到后台运行。
 -e,  --execute=COMMAND   运行 `.wgetrc'-那样的命令。

日志和输入文件:
 -o,  --output-file=FILE    将日志记录到文件 FILE.
 -a,  --append-output=FILE  添加消息到文件 FILE.
 -d,  --debug               输出大量调试信息。
 -q,  --quiet               静默模式 (无输出)。
 -v,  --verbose             显示信息 (默认打开).
 -nv, --no-verbose          显示很少信息但不是完全安静.
 -i,  --input-file=FILE     下载存储在 FILE 文件中的所有URL地址指向的文件。
 -F,  --force-html          把输入文件当成 HTML.
 -B,  --base=URL            prepends URL to relative links in -F -i file.

下载:
 -t,  --tries=NUMBER            设定重试次数(0 一直重试)。
      --retry-connrefused       retry even if connection is refused.
 -O,  --output-document=FILE    写入文档到 FILE.
 -nc, --no-clobber              跳过将要到已存在文件的下载。
 -c,  --continue 续传下载。
      --progress=TYPE           select progress gauge type.
 -N,  --timestamping            don't re-retrieve files unless newer than
                                local.
 -S, --server-response 显示服务器的响应。
      --spider                  什么都不下载
 -T, --timeout=SECONDS 把所有超时时间设为SECONDS秒。
      --dns-timeout=SECS 把DNS超时时间设为SECS秒。
      --connect-timeout=SECS    设定连接超时为 SECS.
      --read-timeout=SECS       设定读取超时为 SECS.
 -w,  --wait=SECONDS            wait SECONDS between retrievals.
      --waitretry=SECONDS       wait 1..SECONDS between retries of a retrieval.
      --random-wait             wait from 0...2*WAIT secs between retrievals.
 -Y,  --proxy                   显示打开代理
      --no-proxy                显示关闭代理
 -Q,  --quota=NUMBER            set retrieval quota to NUMBER.
      --bind-address=ADDRESS    bind to ADDRESS (hostname or IP) on local host.
      --limit-rate=RATE 把下载速度限制为RATE。
      --no-dns-cache 禁止查找DNS缓存。
      --restrict-file-names=OS  restrict chars in file names to ones OS allows.
 -4, --inet4-only 仅连接IPv4地址。
 -6,  --inet6-only              只连接到 IPv6 地址。
      --prefer-family=FAMILY    connect first to addresses of specified family,
                                one of IPv6, IPv4, or none.
      --user=USER 把ftp和http的用户名设定为UESR。
      --password=PASS 把ftp和http的密码设定为PASS。

目录:
 -nd,--no-directories 不建立文件夹。
 -x,--force-directories 强制建立文件夹。
 -nH, --no-host-directories      不创建主机目录。
      --protocol-directories     use protocol name in directories.
 -P,  --directory-prefix=PREFIX  将文件保存到 PREFIX/...
      --cut-dirs=NUMBER          ignore NUMBER remote directory components.

HTTP 选项:
      --http-user=USER        将 http用户设为 USER.
      --http-password=PASS    将http密码设为 PASS.
      --no-cache              不接受服务器缓存的数据.
 -E,--html-extension 以'.html'扩展名保存HTML文档。
      --ignore-length         ignore `Content-Length' header field.
      --header=STRING         insert STRING among the headers.
      --proxy-user=USER       设定 USER 作为代理用户名。
      --proxy-password=PASS   设定 PASS 作为代理密码。
      --referer=URL           include `Referer: URL' header in HTTP request.
      --save-headers          保存 HTTP 头到文件。
 -U,  --user-agent=AGENT      identify as AGENT instead of Wget/VERSION.
      --no-http-keep-alive    disable HTTP keep-alive (persistent connections).
      --no-cookies            不使用cookies.
      --load-cookies=FILE 在会话前从文件中读取cookies。
      --save-cookies=FILE     在会话结束后保存 cookies 到 FILE。
      --keep-session-cookies  load and save session (non-permanent) cookies.
      --post-data=STRING      use the POST method; send STRING as the data.
      --post-file=FILE        use the POST method; send contents of FILE.

HTTPS (SSL/TLS) 选项:
      --secure-protocol=PR     choose secure protocol, one of auto, SSLv2,
                               SSLv3, and TLSv1.
      --no-check-certificate   don't validate the server's certificate.
      --certificate=FILE       client certificate file.
      --certificate-type=TYPE  client certificate type, PEM or DER.
      --private-key=FILE       private key file.
      --private-key-type=TYPE  private key type, PEM or DER.
      --ca-certificate=FILE    file with the bundle of CA's.
      --ca-directory=DIR       directory where hash list of CA's is stored.
      --random-file=FILE       file with random data for seeding the SSL PRNG.
      --egd-file=FILE          file naming the EGD socket with random data.

FTP 选项:
      --ftp-user=USER         设置ftp用户为 USER.
      --ftp-password=PASS     设置ftp密码为 PASS.
      --no-remove-listing     don't remove `.listing' files.
      --no-glob               turn off FTP file name globbing.
      --no-passive-ftp        disable the "passive" transfer mode.
      --retr-symlinks         when recursing, get linked-to files (not dir).
      --preserve-permissions  preserve remote file permissions.

递归下载:
 -r,  --recursive          specify recursive download.
 -l,  --level=NUMBER       maximum recursion depth (inf or 0 for infinite).
      --delete-after       delete files locally after downloading them.
 -k,  --convert-links      make links in downloaded HTML point to local files.
 -K,  --backup-converted   before converting file X, back up as X.orig.
 -m,  --mirror             shortcut for -N -r -l inf --no-remove-listing.
 -p,  --page-requisites    get all images, etc. needed to display HTML page.
      --strict-comments    turn on strict (SGML) handling of HTML comments.

Recursive accept/reject:
 -A,  --accept=LIST               comma-separated list of accepted extensions.
 -R,  --reject=LIST               comma-separated list of rejected extensions.
 -D,  --domains=LIST              comma-separated list of accepted domains.
      --exclude-domains=LIST      被拒绝的域名的用逗号分开的列表。
      --follow-ftp                follow FTP links from HTML documents.
      --follow-tags=LIST          comma-separated list of followed HTML tags.
      --ignore-tags=LIST          comma-separated list of ignored HTML tags.
 -H,  --span-hosts                当递归时转到陌生的主机。
 -L,  --relative                  只跟随相对链接。
 -I,  --include-directories=LIST  允许的目录的列表。
 -X,  --exclude-directories=LIST  不包括的目录的列表。
 -np, --no-parent                 don't ascend to the parent directory.

CONTINUE
INFO: 2008-09-05 02:21:21 | purpen | digg | link

[转载]说一说羽毛球的几种概念

手指发力:是指在球拍与球接触刹那,通过手指突然收紧,产生力量,使球拍面方向转换或加快挥拍速度。 应用:该项发力是击球动作最重要的一个环节,它是调整击球方向和调整击球距离的关键,也是快速提高技能的捷径。 1、捻动发力:动作如关水阀门,四指以顺时针方向旋转来搓动球拍柄,使拍面旋转。 应用:主要应用于网前力量较小的搓、推等动作。 2、屈指发力:拇指、食指扣紧拍柄为支点,其余三指由松到屈指握紧发力。 应用:主要用于需发力的动作,如高远球、平高球、抽球、杀球等。 3、屈捻发力:其动作界于上面两者之间,所发力量要比捻动大而比屈指发力小,是上述两者动作的结合。 应用:多用于后场的吊球、劈吊。 4、小臂的内旋与外旋:把手掌平放,让手背朝上的动作即为内旋,从手背转到手心即为外旋。 应用:此动作多用于高远球、平高球、杀球、抽球等动作的发力,其作用一为调整击球的拍面,二为增加击球瞬间的爆发力。 5、手腕的内收与外展:将手臂平放,手掌直立形同握手,手掌向上抬为外展,向下压为内收。 应用:多用于反手击球。 6、手腕的前屈、后伸发力:将手臂平放,手背朝上,当手腕向下压时为前屈,手腕向上抬为后伸。 应用:后场大力杀球、平高球、挑球等动作。 7、拉拍:手臂上举伸直,然后沉肘,使球拍向前下方运动。 应用:多用于击球点较低时击球,属于被动击球。如中场平抽球,近网球,后场的过渡球或在假动作中出现。 该动作的使用应特别注意,在主动击球时极少使用,但因该动作能产生较大的爆发力,故许多选手已习惯性使用,并使主动击球动作变形,影响技术的发展和攻击力的减弱。 8、起动:是在比赛场上使用最多的动作,也是胜负关键的一环。其动作为持拍手侧的脚略靠前,另一脚后撤半个脚(特殊情况除外),准备时,两脚不能站实(即以全脚掌着地),这样不利于蹬地起动,而应稍提脚跟,双膝微屈,沉肩坐腰,持拍于胸腹之间,并使两脚保持微动。起动一刹那要注意调整重心。一般为重心与去的去的方向相反。如要上右手网前,重心应先移至左脚,要上左手网前,重心移至右脚,这样是为了产生爆发力,提高起动速度。 CONTINUE
INFO: 2008-09-04 06:49:48 | purpen | digg | link

[转载]在Nginx环境下用Perl FastCGI支持Awstats

日志统计分析软件Awstats需要Perl支持,但是Nginx内建的Perl模块目前还并不稳定,经常会出问题,所以还是用FastCGI模式运行Perl比较可靠。下面就谈谈如何在Nginx下配置Perl的FastCGI模式:

首先,安装Perl的FastCGI模块:

#wget http://www.cpan.org/modules/by-module/FCGI/FCGI-0.67.tar.gz
#tar zxvf FCGI-0.67.tar.gz
#cd FCGI-0.67
# perl Makefile.PL
#make && make install

其实也可以用这种方法:#perl -MCPAN -e ‘install FCGI’

然后,配置Perl的FastCGI脚本(从网上找到的,未找到原始出处):

#!/usr/bin/perl
use FCGI;
use Socket;
use POSIX qw(setsid);
require ’syscall.ph’;
&daemonize;
END() { } BEGIN() { }
*CORE::GLOBAL::exit = sub { die “fakeexit\nrc=”.shift().”\n”; };
eval q{exit};
if ($@) {
exit unless $@ =~ /^fakeexit/;
};
&main;
sub daemonize() {
chdir ‘/’ or die “Can’t chdir to /: $!”;
defined(my $pid = fork) or die “Can’t fork: $!”;
exit if $pid;
setsid or die “Can’t start a new session: $!”;
umask 0;
}
sub main {
$socket = FCGI::OpenSocket( “/tmp/perl_fastcgi.sock”, 10 );
$request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket );
if ($request) { request_loop()};
FCGI::CloseSocket( $socket );
}
sub request_loop {
while( $request->Accept() >= 0 ) {
$stdin_passthrough =”;
$req_len = 0 + $req_params{’CONTENT_LENGTH’};
if (($req_params{’REQUEST_METHOD’} eq ‘POST’) && ($req_len != 0) ){
my $bytes_read = 0;
while ($bytes_read < $req_len) {
my $data = '';
my $bytes = read(STDIN, $data, ($req_len - $bytes_read));
last if ($bytes == 0 || !defined($bytes));
$stdin_passthrough .= $data;
$bytes_read += $bytes;
}
}
if ( (-x $req_params{SCRIPT_FILENAME}) &&
(-s $req_params{SCRIPT_FILENAME}) &&
(-r $req_params{SCRIPT_FILENAME})
){
pipe(CHILD_RD, PARENT_WR);
my $pid = open(KID_TO_READ, "-|");
unless(defined($pid)) {
print("Content-type: text/plain\r\n\r\n");
print "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n";
next;
}
if ($pid > 0) {
close(CHILD_RD);
print PARENT_WR $stdin_passthrough;
close(PARENT_WR);
while(my $s = ) { print $s; }
close KID_TO_READ;
waitpid($pid, 0);
} else {
foreach $key ( keys %req_params){
$ENV{$key} = $req_params{$key};
}
if ($req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/) {
chdir $1;
}

close(PARENT_WR);
close(STDIN);
syscall(&SYS_dup2, fileno(CHILD_RD), 0);
exec($req_params{SCRIPT_FILENAME});
die(”exec failed”);
}
}
else {
print(”Content-type: text/plain\r\n\r\n”);
print “Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n”;
}

}
}

将权限改为可执行,并执行之。

配置nginx.conf,使之支持perl脚本:

location ~* .*\.pl$
{
include awstats.conf;
}

编辑awstats.conf

fastcgi_pass unix:/tmp/perl_fastcgi.sock;
fastcgi_index awstats.pl;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_read_timeout 60;

然后重启nginx:
#service nginx restart

CONTINUE
INFO: 2008-09-04 06:45:15 | purpen | digg | link

[转载]A Beginner's Introduction to POE

What Is POE, And Why Should I Use It?
    回顾一下我们每天写的程序,可以发现这些程序大部分都有着基本的结构:启动,执行一系列的动作,然后退出。对于那些在用户和他们的数据之间不需要很多交互的应用中,这样的程序都能工作得很好。然后,如果是如果是碰到了复杂的任务,我想你就需要一个更加好的程序框架理解任务的复杂性,完成这个任务。
    所以POE(Perl 对象环境)应运而生了。POE是一个构建Perl程序的框架,以更自然地完成那些需要对外部数据作出反应的任务,比如网络通讯或者用户接口。用POE写的程序完全是非线性的;你只需要建立一些小的子程序,并且定义好它们之间如何相互调用,那么POE就会根据程序处理的输入输出,自动在它们之间切换。说到现在,你可能已经头晕了。如果你习惯于看代码去理解,那么看了下面一个小例子后,你就会恍然大悟了。

POE Design
    说POE是一个小的操作系统一点都不夸张,它有它自己的内核,进程,进程间通讯(IPC),驱动等等这些。实际上,它是一个简单的系统,构建了一系列的状态信息。下面对组成POE各个部分的一个简单的描述:
States
    POE的基本程序块就是状态,它是一些代码,当事件发生时触发执行。例如,输入的数据到达,一个会话过期,一个会话传递了一条信息给另一个会话。POE里的每件事情都是基于接收和处理各种各样的事件。
The Kernel
    POE的内核跟操作系统的内核很象:它守护着后台的所有你的进程和数据,安排你的代码的触发。你能够用POE的内核来为你的进程设置警报,控制你的状态队列和其他一些低级服务,当然,大部分时间你不用直接来跟内核交互。
Sessions
    POE里的会话相当于一个真的操作系统里的进程。一个会话就是一个POE程序,当它在运行时不停地在状态之间切换。它能够创建子会话,传递信息给其他的会话等等。每个会话都能通过调用 heap 存储会话特有的数据,这些数据在会话中的各个状态都是可以存取的。
    POE有一个简单的协作的多任务处理模块;每个会话在同一个OS进程中执行,不需要任何线程和进程。对于这样的会话,你应该特别注意在POE程序中使用模块化的系统调用。
    这些就是POE的最基本的部分,但是在我们开始实际的代码前还需要稍微ie解释一些高级的POE的部分。
Drivers
    驱动位于POE最低级的I/O层。目前,只有一个驱动包括在POE的安装中-- POE::Driver::SysRW,它读写文件句柄中的数据。不管怎样,我们都不需要直接使用驱动。
Filters
    过滤器,在某个方面来说,是非常有用的。过滤器是一个简单的接口,转换数据块从一个格式成另一个格式。例如,POE::Filter::HTTPD 能够在 HTTP 1.0 requests 之间 HTTP::Request 对象互相转换。POE::Filter::Line 能够见数据流转换成序列化数据行。
Wheels
    Wheels包含了每天任务的可重复利用的高级逻辑部分。它们是POE封装有用代码的方法。在POE中你需要处理到的Wheels包括事件驱动的输入输出数据和网络连接的创建。Wheels经常使用过滤器和驱动来处理和传递数据。这个描述太过于含糊了,下面的代码将会给出一个例子来说明这个概念。
Components
    组件是一个会话,被设计来受控于其它会话。你的会话能够从它们那里来处理命令和接受事件,这点很象真实操作系统中的通过IPC通讯。一个组件的例子就是POE::Component::IRC,一个创建基于POE的IPC客户端接口,或者是POE::Component::Client::HTTP,一个事件驱动的Perl实现的HTTP用户代理。组件同样是POE非常有用的一个部分。

A Simple Example
    在这个例子中,我们会建立一个守护进程服务端,它接受TCP连接,同时打印由它的客户端提交的算术问题的答案。当有人连接它的端口31008,它将打印“Hello,client”。客户端能够提交一个算术表达式,以一个新行结束提交,服务端将送回表达式的答案。够简单吧。
    写这样一个POE程序跟写一个Unix下的守护进程的传统方法没有什么很大的不同。我们将有一个服务器会话在端口31008监听TCP连接。每当连接到来时,它将创建一个子会话来处理连接。每个子会话都能跟用户交互,然后在连接断开后安静地死掉。所有这些用Perl简单地实现只需要模块化的72行代码就行了。
    这个程序简单地以下面的代码开始:
   1  #!/usr/bin/perl -w
   2  use strict;
   3  use Socket qw(inet_ntoa);
   4  use POE qw( Wheel::SocketFactory  Wheel::ReadWrite
   5              Filter::Line          Driver::SysRW );
   6  use constant PORT => 31008;
这一段我们导入了脚本所需要的模块以及函数,并定义了监听端口的常量值。”use POE;”后面的 qw()语句一次导入了很多POE::模块。
    现在开始本文最酷的部分:
   7  new POE::Session (
   8      _start => \&server_start,
   9      _stop  => \&server_stop,
  10  );
  11  $poe_kernel->run();
  12  exit;
    这样就已经是一个完整的程序了!我建立了服务端会话,告诉POE内核开始执行事件,并且在事件结束后退出。(当没有任何会话需要管理的时候,POE内核就认为事情做完了,但是既然我们已经打算把服务端会话放在一个无穷的循环中,它将不会以这种发式退出)POE在你写"use POE;"h后,自动输出变量$poe_kernel 到你的名字空间中。
    new POE::Session 方法调用需要解释一下。当你创建一个会话时,你给内核一个这个会话将接受事件的列表。在上面的代码中,意味着这个新的会话将通过调用&server_start,&server_stop处理_start和_stop事件。任何一个受到的但没有列举到的事件,将会被会话忽略。_Start和_Stop事件对于一个POE会话来说是一个特殊事件。_start事件是当一个会话创建时第一件要做的事情,当会话将要被摧毁时内核就通知这个会话进入_stop状态。
    现在,我们已经写了完整的程序,我们还要写当会话运行时要执行的状态代码。接下来,让我们以&server_start开始。当主要的服务端会话被创建,开始执行程序时,它将会被调用。

  13  sub server_start {
  14      $_[HEAP]->{listener} = new POE::Wheel::SocketFactory
  15        ( BindPort     => PORT,
  16          Reuse        => 'yes',
  17          SuccessState => \&accept_new_client,
  18          FailureState => \&accept_failed
  19        );
  20      print "SERVER: Started listening on port ", PORT, ".\n";
  21  }

    这是一个有关POE状态的很好的例子。首先:看到变量$_[HEAP]了吗?POE有一个特殊的方法来传递参数。@_数组是由许多外部的参数打包在一起的。外部参数包括目前内核,会话和状态名的一个引用,堆栈的引用,以及其它一些东西。我们可以用POE导出的特殊常量来作为这个数组索引,比如 HEAP, SESSION, KERNEL, STATE和ARG0~ARG9(用户提供的参数)。跟POE的大部分设计一样,这样子的安排能够最大化后面的兼容性而又不牺牲速度。上面的例子存储了一个 SocketFactory wheel 在键值 listen 下。
    POE::Wheel::SocketFactory wheel是POE里最酷的东西之一。你能够用它创建任何一个流socket(UDP socket还不行),而不需要担心细节。上面的代码将创建一个SocketFactory来监听特殊的TCP端口的新连接。当连接建立时,它将调用&accept_new_client来传递一个新的客户端,如果在这其中发生错误了,它将调用&accept_failed,而不是让我们自己来处理错误。这差不多就是用POE在网络中要做的。
    我们存储一个wheel在堆栈中,以防止在状态的最后被Perl的垃圾收集机制意外地消灭掉,——这个方法在会话的每个状态中到处存在。现在我们来看&server_stop 状态的代码:

  22  sub server_stop {
  23      print "SERVER: Stopped.\n";
  24  }


这段不需要多解释了。接下来的是我们创建一个新的会话来处理每个新到的连接。

  25  sub accept_new_client {
  26      my ($socket, $peeraddr, $peerport) = @_[ARG0 .. ARG2];
  27      $peeraddr = inet_ntoa($peeraddr);
  28      new POE::Session (
  29          _start => \&child_start,
  30          _stop  => \&child_stop,
  31          main   => [ 'child_input', 'child_done', 'child_error' ],
  32          [ $socket, $peeraddr, $peerport ]
  33      );
  34      print "SERVER: Got connection from $peeraddr:$peerport.\n";
  35  }
当客户端成功地建立了跟服务端的连接后,我们的 POE::Wheel::SocketFactory将调用这个子例程。
我们将socket地址转换成人可读的IP地址,并且建立一个新的会话来跟客户端通讯。这跟前面的
POE::Session 构造器很象,但是有几点在接下来要说明。
    @_[ARG0 .. ARG2]是($_[ARG0], $_[ARG1], $_[ARG2])的快捷方式。你会在POE程序中
看到很多这样的数组切片。
    看31行:好像有点奇怪,其实这是一种很聪明的缩写。它可以用下面的比较长的方法来重写:
new POE::Session ( ... child_input => &main::child_input, child_done => &main::child_done, child_error => &main::child_error, ... );
    这是一个方便的做法来写出很多的状态名字,这些名字跟事件的名字是一样的。——你可以传递包名或者
对象来作为键,或者是任何一个有子例程,方法名组成的数组引用。可以参考POE::Session得到更多的信息。
    最后,在POE::Session 构造器参数列表最后的数组引用是我们要手动传递给_start状态的参数列表。
    如果POE::Wheel::SocketFactory在创建监听端口或者接受连接时产生了问题,下面的会发生:
36 sub accept_failed { 37 my ($function, $error) = @_[ARG0, ARG2]; 38 delete $_[HEAP]->{listener}; 39 print "SERVER: call to $function() failed: $error.\n"; 40 }

    打印错误信息是正常的处理方式,但是我们为什么还要从堆栈中删除SocketFactory wheel呢?答案在于
POE管理会话资源的方式。只要会话还能产生和接受事件,那么它就被认为是活动的。如果没有wheel,POE内核
会认为会话已经死了,并收集会话的资源。服务端得到事件的唯一方式就是从SocketFactory wheel,如果
它被消灭了,POE内核会一直等待,直到所有它的子会话结束,再收集所有占用的资源。在这一点上,既然
已经没有剩下的会话需要执行,POE内核将会结束并退出。
    所以,基本上来说,这是最通常的结束POE会话的方法:结束所有会话资源,让内核干剩下的工作。现在,
我们谈到子会话的细节。
    
  41  sub child_start {
  42      my ($heap, $socket) = @_[HEAP, ARG0];
  43      $heap->{readwrite} = new POE::Wheel::ReadWrite
  44        ( Handle => $socket,
  45          Driver => new POE::Driver::SysRW (),
  46          Filter => new POE::Filter::Line (),
  47          InputState => 'child_input',
  48          ErrorState => 'child_error',
  49        );
  50      $heap->{readwrite}->put( "Hello, client!" );
  51      $heap->{peername} = join ':', @_[ARG1, ARG2];
  52      print "CHILD: Connected to $heap->{peername}.\n";
  53  }
    每当新的子会话被创建来处理最新的连接客户端时上面的代码就会被调用。这里我们要介绍一种新的
POE wheel:ReadWrite wheel,这是一个由事件驱动的处理I/O任务的wheel。我们把它传递给文件
句柄,一个驱动,一个过滤器等等。接着,每当新的数据到达文件句柄时,wheel将发送一个child_input
事件给会话,如果有任何错误发生就会发送一个child_error 事件。
    我们理解用这个新的wheel来输出字符串”Hello,client”给socket。最后,我们存储在堆栈中
的客户端地址和端口,并打印成功信息。
    我们省略了 child_stop 的状态讨论。它只有一行长度。现在我们直接看主要的child_input 程序。
  57  sub child_input {
  58      my $data = $_[ARG0];
  59      $data =~ tr{0-9+*/()-}{}cd;
  60      return unless length $data;
  61      my $result = eval $data;
  62      chomp $@;
  63      $_[HEAP]->{readwrite}->put( $@ || $result );
  64      print "CHILD: Got input from peer: \"$data\" = $result.\n";
  65  }
    当客户端发送给我们一行数据,我们取得里面简单的算术表达式并eval它,然后把结果或者错误信息
发送给客户端。通常情况下,将客户端发送来的不可信任的数据直接就eval是非常危险的,所以我们要确保
在eval前,将字符串中所有的非数学字符全部过滤掉。子会话将一直保持接受数据直到客户端断开。
    所有事件驱动的应用都是使用POE的好地方。
源代码:http://www.perl.com/2001/01/poe-math3.pl

CONTINUE
INFO: 2008-09-01 03:33:11 | purpen | digg | link

[转载]mogileFS体系结构分析-数据库表

前面对mogileFS做了一下简单介绍,这儿开始对他进行剖析。
首先剖析他用来做文件西信息track的表结构。
使用到的数据表

  • server_settings
  • 服务器的一些配置信息,采用key=>value的记录方式保存。

  • domain
  • 域定义

  • hosts
  • 主机定义,主机的ip,存储节点服务所开的端口等信息。

  • device
  • 主机上的可用设备定义,包括设备可用空间,使用的权重等信息,由存储服务定时更新设备的情况。

  • class
  • 文件分类定义

  • file
  • 记录文件的基本信息,属于什么类别,他的key和文件大小等信息

  • tmpfile
  • 复制的临时文件信息?

  • file_to_delete
  • 记录要做删除的文件

  • file_to_delete_later
  • 要延迟删除的文件

  • file_on
  • 记录什么设备上有什么文件,一个文件在不同设备上的存储各有一条记录。

  • file_on_corrupt
  • 损坏的文件,哪一个文件在什么设备上损坏了。

  • file_to_replicate
  • 要做分发的文件,记录来源设备,失败次数和下次重试的时间等信息。

  • fsck_log
  • 文件检查日志

  • unreachable_fids
  • 不可到达的文件列表

mogileFS是一个依赖数据库做数据信息交换的系统,为了减少DB的操作次数,使用了memcached做一些查询结果的缓冲。

CONTINUE
INFO: 2008-08-19 07:57:02 | purpen | digg | link

[转载]mogileFS的工作方式(译)

原文地址: mogileFS HighLevel Overview

下面简要阐述 MogileFS 是怎么工作的.

mogileFS由如下一些部分构成:

  • Application: 想要 保存/加载 文件的应用
  • Tracker (the mogilefsd process): 基于事件的(event-based) 父 进程/消息 总线来管理所有来之于客户端应用的交互(requesting operations to be performed), 包括将请求负载平衡到 “query workers” 中,让mogilefsd的子进程去处理. 你可以在不同的机器上运行两个Tracker, 为了高可用性, 或使用更多的Tracker为了负载平衡(你需要运行多于两个的Tracker). mogilefsd的子进程有:
    • Replication — 个机器间复制文件
    • Deletion — 从命名空间删除是立即的,从文件系统删除是异步的
    • Query — 响应客户端的请求
    • Reaper — 在磁盘失败后将文件复制请求重新放到队列中
    • Monitor — 监测主机和设配的健康度和状态
  • Database — 数据库用来存放MogileFS的元数据 (命名空间, 和文件在哪里). 这应该设置一个高可用性(HA)的环境以防止单点失败.
  • Storage Nodes — 实际文件存放的地方. 存储节点是一个HTTP服务器,用来做 删除,存放等事情,任何WebDAV服务器都可以, 不过推荐使用 mogstored 。 mogilefsd 可以配置到两个机器上使用不同端口… mogstored 为所有 DAV 操作 (和流量监测), 并且你自己选择的快速的HTTP服务器用来做 GET 操作(给客户端提供文件). 典型的用户没一个加载点有一个大容量的 SATA 磁盘,他们被加载到 /var/mogdata/devNN.

High-level 流程:

  • 应用程序请求打开一个文件 (通过RPC 通知到 tracker, 找到一个可用的机器). 做一个 “create_open” 请求.
  • tracker 做一些负载均衡(load balancing)处理,决定应该去哪儿,然后给应用程序一些可能用的位置。
  • 应用程序写到其中的一个位置去 (如果写失败,他会重新尝试并写到另外一个位置去).
  • 应用程序 (client) 通过”create_close” 告诉tracker文件写到哪里去了.
  • tracker 将该名称和域命的名空间关联 (通过数据库来做的)
  • tracker, 在后台, 开始复制文件,知道他满足该文件类别设定的复制规则
  • 然后,应用程序通过 “get_paths” 请求 domain+key (key == “filename”) 文件, tracker基于每一位置的I/O繁忙情况回复(在内部经过 database/memcache/etc 等的一些抉择处理), 该文件可用的完整 URLs地址列表.
  • 应用程序然后按顺序尝试这些URL地址. (tracker’持续监测主机和设备的状态,因此不会返回死连接,默认情况下他对返回列表中的第一个元素做双重检查,除非你不要他这么做..)
CONTINUE
INFO: 2008-08-19 07:45:15 | purpen | digg | link

Copyright © 2008 Jaever. All rights reserved.

This Site looks and works best when viewed using browsers enabled with JavaScript 1.5 and CSS, such as Firefox 1+ or Safari 3+.