2008年12月26日星期五

Re: [PerlChina] 请问有什么便捷的方法载入zip包里的库?

就算没有的话,用来包装桌面程序也不错 :)

2008/12/26 cnhack TNT <cnhacktnt@gmail.com>:
> 呵呵,用 PAR 应该满足你的要求,只是不知道你的服务器空间是否有 PAR,或者支持自己安装 PAR 模块
>
> 2008/12/25 agentzh <agentzh@gmail.com>
>>
>> 2008/12/25 Luo Yong <luo.yong.name@gmail.com>
>>>
>>> 多谢,
>>>
>>>
>>> 这个方法大概是最好的方法了,不过感觉Java的那种用JAR文件封装类库的方法很方便,但是在perl上暂时没办法实现,不知道perl6里有没有类似的功能。
>>>
>>
>> CPAN 上有一个叫做 pp 的工具可以把 Perl 5 类库封成 PAR 文件 ;)
>>
>> 基于 parrot 的 Perl 6 中可以在字节码级别进行联编,就更方便了 ;)
>>
>> -agentzh
>>
>> _______________________________________________
>> China-pm mailing list
>> China-pm@pm.org
>> http://mail.pm.org/mailman/listinfo/china-pm
>
>
> _______________________________________________
> China-pm mailing list
> China-pm@pm.org
> http://mail.pm.org/mailman/listinfo/china-pm
>
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 请问有什么便捷的方法载入zip包里的库?

多谢,需要的就是这个 :)

2008/12/25 agentzh <agentzh@gmail.com>:
> 2008/12/25 Luo Yong <luo.yong.name@gmail.com>
>>
>> 多谢,
>>
>>
>> 这个方法大概是最好的方法了,不过感觉Java的那种用JAR文件封装类库的方法很方便,但是在perl上暂时没办法实现,不知道perl6里有没有类似的功能。
>>
>
> CPAN 上有一个叫做 pp 的工具可以把 Perl 5 类库封成 PAR 文件 ;)
>
> 基于 parrot 的 Perl 6 中可以在字节码级别进行联编,就更方便了 ;)
>
> -agentzh
>
> _______________________________________________
> China-pm mailing list
> China-pm@pm.org
> http://mail.pm.org/mailman/listinfo/china-pm
>
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

昨天就看到咯,微软开始收拢人心了!
--
blog : http://hi.baidu.com/smallfish7788

--------------------------------------------------
From: "joe jiang" <lamp.purl@gmail.com>
Sent: Friday, December 26, 2008 5:38 PM
To: <china-pm@pm.org>; <perlchina@googlegroups.com>
Subject: Re: [PerlChina] 答复: 各位圣诞快乐哦!

> 刚刚发现错过了 infoQ 的一篇不错的文章。
> http://www.infoq.com/cn/news/2008/12/CPAN-Win32
>
> 非常适合作为 CPAN 作者的圣诞节礼物 :)
>
> On 四, 2008-12-25 at 21:58 +0800, Jacky Xu wrote:
>> <--
>> http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/
>>
>> Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的进
>> 程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者当子
>> 进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。Proc::Harness
>> 脚本自身则是挂在了 deamontools 之下。 -->
>>
>> 貌似这个我有需求,监控进程,丢失后立刻重启
>>
>>
>> 在 2008-12-25四的 15:13 +0800,agentzh写道:
>> > 2008/12/25 wbi 畢 <wbisearchina@hotmail.co.jp>
>> > >
>> > > Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?
>> >
>> > =head1 NAME
>> >
>> > List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓
>> > 爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。
>> >
>> > =head1 背景
>> >
>> > 在我们的生活搜索项目中,需要对网页进行深层次的识别和抽取。基于文本内容
>> > 的分类我们目前采用的是美国雅虎基于最大熵的 DCP 系统。而对于网页结构方
>> > 面的分类(即这个网页是列表页呢,还是详情页?),以及主体链接列表、主体
>> > 区域抽取,则一直缺乏比较好的解决方案。我的同事尝试过通过纯粹的结构化的
>> > 方法(如海维算法)进行识别,准确率只有 60%,而基于 SVM 这样的机器学习
>> > 的方法,对网页类型比较敏感,如目标网页与训练集相差较多,则准确率迅速下
>> > 降。
>> >
>> > 于是我尝试把网页显示时的视觉信息结合到海维算法以及块合并算法中。于是准
>> > 确率和召回率分别达到了 90% 和 80%。这里的视觉信息主要包括一个网页区域
>> > 的大小、形状、和在整个页面中的位置。更多的信息还包括字体、颜色等等。这
>> > 样,便诞生了 List Hunter 插件。于是如何将 Firefox 插件做成一个大规模的
>> > 集群用于生产,便成为了重要问题。
>> >
>> > 在下面这篇 blog 文章中我介绍了更多背景方面的细节以及 List Hunter 插件
>> > 本身的情况:
>> >
>> > http://blog.agentzh.org/#post-97
>> >
>> > =head1 集群的结构
>> >
>> > 该集群由四大部分组成:纯 Firefox 集群,Apache + mod_proxy +
>> > mod_disk_cache 集群,curl 预取器集群,和 OpenResty 集群。一共有十几台
>> > 生产机"全职"或者"兼职"地参与了这个集群。下面逐一介绍一下哈:
>> >
>> > =over
>> >
>> > =item 纯 Firefox 集群
>> >
>> > 纯 Firefox 集群目前由 8 台 4 核的 redhat5 生产机组成。每台生产机运行 3
>> > 个 Firefox 3.1 进程实例。因为那 8 台机器同时服务于淘宝 VIP 搜索的商口
>> > 图片显示接口(大约 600 万日 PV),所以我们没敢在这些机器上运行比较多的
>> > Firefox 进程。
>> >
>> > 需要指出的是,Firefox 默认是"进程复用"的运行方式。即启动多次
>> > firefox-bin 可执行程序,其实得到的还是单个 Firefox 进程。这种进程复用
>> > 方式无法充分利用生产机的多核 CPU。因为在任意给定时刻,一个进程只能跑在
>> > 一个核上,哪怕它是多线程的。为了让 Firefox 以多进程方式运行,需要:
>> >
>> > =over
>> >
>> > =item 1.
>> >
>> > 在调用 firefox-bin 程序时指定 -no-remote 命令行选项,或者设置环境变量
>> > MOZ_NO_REMOTE=1
>> >
>> > =item 2.
>> >
>> > 以不同的 profile 运行不同的 firefox-bin 进程(利用 -P 命令行选项)。
>> >
>> > =back
>> >
>> > 我们平常看到的 Firefox 的主窗口并不启动,而以 chrome 方式单独运行 List
>> > Hunter 插件的界面,例如:
>> >
>> > firefox -chrome chrome://listhunter/content/crawler.xul -P
>> > crawler2 -no-remote
>> >
>> > 以 chrome 方式运行的插件与 XULRunner 方式运行的 XUL 应用是很类似的。
>> >
>> > 由于 Firefox 3.1 还没有正式发布,我直接 checkout 官方 Mercurial 源码仓
>> > 库内的最新版本,自己在我们的 redhat 生产机上编译的。我们目前几乎没有修
>> > 改官方的 C++ 源代码,为了方便和官方版本保持同步。我们目前使用的是下面
>> > 的 firefox 编译选项:
>> >
>> > # My .mozconfig
>> > mk_add_options MOZ_MAKE_FLAGS="-j2"
>> > mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
>> > ac_add_options --enable-crypto --enable-feeds
>> > --disable-profilesharing --enable-rdf --enable-zipwriter
>> > --disable-tests --disable-gnomeui --disable-cookies --disable-canvas
>> > --disable-gnomeui --disable-inspector-apis --disable-mailnews
>> > --disable-mathml --disable-official-branding
>> > --enable-plaintext-editor-only --disable-postscript --disable-printing
>> > --disable-profilelocking --disable-safe-browsing
>> > --disable-startup-notification --disable-svg
>> > --disable-svg-foreignobject --disable-updater --disable-javaxpcom
>> > --disable-plugins --disable-crashreporter --disable-tests
>> > --disable-debug --enable-application=browser --build=i686-linux
>> > --disable-jsd --disable-ldap --enable-strip --disable-accessibility
>> > --disable-ogg --disable-dbus --disable-freetype2 --disable-optimize
>> >
>> > 这里能禁用的功能我们都禁用了,这里的 feeds, rdf, crypto 这三个都不能
>> > disable,否则源码编译不通过,会报一些 .h 头文件找不到,呵
>> > 呵。--disable-ogg 实际上也不起作用,但网上的材料看曾经有效过,呵呵。
>> >
>> > 事实上,目前我们还是给官方的源码打了一个 C++ 补丁,用于将 Error
>> > Console 中的 Errors 重定向到 stderr,这样方便我们在集群环境下通过
>> > Firefox 进程的 log 文件捕捉和诊断一些异常。目前的补丁是下面这个样子:
>> >
>> > http://agentzh.org/misc/191src.patch.txt
>> >
>> > 值得一提的是,Firefox 进程本身是"无头"的,即它运行在 Xvfb 这个 X
>> > server 之上,只在内存里执行渲染,而不需要任何显示硬件的存在。这些
>> > Firefox 进程本身是挂在我们自己的一个 Perl 写的进程监控脚本之下。该脚本
>> > 来自我们的 Proc::Harness 模块:
>> >
>> >
>> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/
>> >
>> > Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的
>> > 进程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者
>> > 当子进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。
>> > Proc::Harness 脚本自身则是挂在了 deamontools 之下。
>> >
>> > 这些 Firefox 进程受安装在其中的 List Hunter 插件的完全控制。它们都是高
>> > 度自治的 robot。它们内部有一个处理循环,一批一批地从 OpenResty 的 web
>> > service 接口取到 URL 任务,然后一个一个地在 Firefox 的 browser 组件里
>> > 加载和分析,最后把分析到的结果一批一批地通过 OpenResty 提交之。
>> >
>> > =item curl 预取爬虫集群与 Apache mod_proxy 集群
>> >
>> > 该集群目前布署了 6 台双核的 redhat4 生产机。每台机器都安装了两个集群组
>> > 件,一是预取器,一是 Apache mod_proxy. 预取器的作用是通过 curl (准确
>> > 地说是 WWW::Curl 模块)将网页的 HTML 和 CSS 通过 mod_proxy 预取一遍,
>> > 这样这些请求的结果就可以在 mod_proxy 中通过 mod_disk_cache 缓存住。于
>> > 是当纯 Firefox 集群再通过 mod_proxy 去抓这些 URL 时,mod_proxy 就可以
>> > 直接把缓存后的结果直接返回给 Firefox 了。
>> >
>> > 预取器和 Firefox 进程是同时工作的,但对于一个 URL 任务而言,只有通过预
>> > 取器预取过之后,Firefox 进程才会进行处理。所以实际构成了一个两道工序的
>> > 流水线。这种调度是由 OpenResty 集群来完成的。
>> >
>> > 预取器目前是以一个叫为 WWW::Prefetcher 的 Perl 模块的形式来实现的:
>> >
>> >
>> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/WWW-Prefetcher/
>> >
>> > 虽然 mod_cache 提供了许多选项,但其缓存行为还是比较遵守 RFC 的 cache
>> > 要求的。因此我对 mod_cache 模块进行了许多修改,使之可以无条件地缓存住
>> > 请求过的所有网页,而不论其 URL 是否有 querystring,也不论其 response
>> > header 中的要求是什么。我们对最新的 httpd 2.2.11 的补丁如下:
>> >
>> > http://agentzh.org/misc/httpd-2.2.11.patch.txt
>> >
>> > 特别地,mod_disk_cache 指向的不是磁盘目录,而是 RAM 中开辟的 tmpfs 分
>> > 区。由于我们这 6 台机器都是很旧的 IDE 硬盘,因此直接用磁盘作 cache 存
>> > 储时,高并发条件下,每台机器的 load 都在 20 以上,根本无法忍受。后来换
>> > 为 tmpfs 结果 htcacheclean 工具之后,机器负载就降到 0.1 以下了。
>> >
>> > =item OpenResty集群
>> >
>> > 由于 OpenResty 的通用性,我们直接复用了同时服务于 yahoo.cn 和口碑网的
>> > 那个生产集群,(3 台 FastCGI 前端机和1 台 PL/Proxy 机器),所以我就没
>> > 有布署新的机器。在服务于 Firefox 集群的 OpenResty 接口中通过 View API
>> > 暴露了若干的 PostgreSQL 函数,以完成整个 List Hunter 集群的任务调度和
>> > 结果汇总。目前的实现中,我们通过 Pg 的 sequence 摸拟了一种循环任务队
>> > 列,并通过计数器完成流水线中两道工序之间的相对同步。
>> >
>> > 相关的 Pg 函数、sequence、以及索引的定义在这里:
>> >
>> >
>> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-db.sql
>> >
>> > 相关的 OpenResty 对象的定义则在这里:
>> >
>> >
>> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-resty.pl
>> >
>> > =back
>> >
>> > =head1 集群的性能
>> >
>> > 集群目前每小时的产出稳定在 10 万网页以上,一天的产出在 240 万以上。
>> > Firefox 机器的负载在 3 左右,Proxy 的负载在 0.1 以下。
>> >
>> > JS 基准测试显示 Firefox 3.1 加载一个页面的平均延时是 200 ~ 300 ms,机
>> > 房间的网络延时在 10 ~ 20 ms(因为网页已被 mod_cache 缓存住,故无到外网
>> > 的网络开销), List Hunter 插件的 DOM 分析代码的用时在 200 ~ 300 ms。其
>> > 他 OpenResty 开销再计入,大约 1 sec 处理一个页面。
>> >
>> > =head1 已知瓶颈和缺陷
>> >
>> > 当 OpenResty 中的 URL 任务表的行数超过 100 ~ 200 万时,调度查询容易超
>> > 过 PL/Proxy 的 10 秒限制。因此,我们目前采取"流式"的任务导入和导出方
>> > 式。通过 cronjob 定期地向库中导入任务,并同时把完成了的任务及时移出。
>> >
>> > Apache 的 mod_proxy 在高并发条件下不够稳定,而且限于 Apache 自身的体系
>> > 结构,无法实现 proxy pipelining. 因此计划在未来集群规模进一步扩大时,
>> > 改用 Squid. 当然了,Squid 很可能也需要进行修改才能满足我们这里的强制缓
>> > 存一段指定时间的需求。
>> >
>> > 同时,受限于 Apache mod_cache 后端的非分布式,代理服务器的调度是在
>> > Firefox 进程和 curl 预取进程中完成的,导致前端代码比较复杂,还带来了代
>> > 理服务器列表的定时同步问题。因此,未来可以考虑为 Apache mod_cache 或者
>> > Squid 添加 memcached 缓存后端的支持。这样代理前端的多台服务器可以实现
>> > 对集群内其他部件的"透明化"。
>> >
>> > =head1 TODO
>> >
>> > =over
>> >
>> > =item 1.
>> >
>> > 换用 Squid + memcached 作为缓存用正向代理
>> >
>> > =item 2.
>> >
>> > 通过 XULRunner 而非 firefox -chrome 方式运行 List Hunter 插件。(需要
>> > 为我的 XUL::App 框架添加 XULRunner 支持)
>> >
>> > =back
>> >
>> > =head1 与相似产品的异同
>> >
>> > 美国雅虎通过大量修改 Firefox 2 的 C++ 源代码,开发了叫为 HLFS 的爬虫集
>> > 群,用于爬取 AJAX 网站的内容以及得到带有视觉信息的 DOM 树。他们将
>> > Firefox 进程做成了 HTTP 代理的形式,对外部应用提供服务。
>> >
>> > 而我们的 List Hunter 集群中的 Firefox 进程则是高度自治的爬虫,它们自己
>> > 从 OpenResty 中不断地批量取任务去完成。而外部应用则是批量地向
>> > OpenResty 导入任务来让集群运转。由于 List Hunter 集群并没怎么修改
>> > Firefox 的源代码,这使得我们可以很容易地与官方最新版本保持同步,从而第
>> > 一时享受到官方优化带来的众多好处。
>> >
>> > 同时 List Hunter 集群本身是通用目的的,它可以作为各种 Firefox 插件
>> > 的"集群容器"。换言之,这是一种将 Firefox 插件"集群化"的完整的框架。
>> >
>> > 由于 Firefox 插件开发本身已经通过我发布到 CPAN 的 XUL::App 框架得到了
>> > 极大的简化,所以响应新的需求的成本是非常低的。
>> >
>> > =head1 使用 Firefox 的利与弊
>> >
>> > =over
>> >
>> > =item 优点
>> >
>> > Firefox 是世界级的浏览器。作为最复杂功能最丰富的 Internet 客户端之一,
>> > 我们将之作为爬虫可以享受到和最终用户一样的丰富功能,无论是 AJAX 还是视
>> > 觉信息都不是问题。
>> >
>> > Firefox 有基于 XUL 和 chrome JS 的灵活的插件机制,极易扩展。事实上,
>> > Firefox 主界面自身就是一个大插件。同时,Gecko 是基于 XPCOM 组件方式
>> > 的,因此可以很容易地使用 C/C++/Java 等语言开发 XPCOM 组件,然后再用
>> > JavaSscript 把它们粘合在一起。于是乎,JavaScript 成为了像 Perl 一样的
>> > 胶水类语言。
>> >
>> > 运行于 Gecko 之上的插件 JavaScript 拥有最高权限,这种 JS 可以访问磁盘
>> > 文件,可以访问系统环境变量,可以使用原生的 XmlHttpRequest 对象发出跨域
>> > AJAX 请求。
>> >
>> > Firefox 的性能随着新版本的发布总会有戏剧性的变化。Firefox 3.1 中的
>> > Gecko 引擎的渲染速度就比 3.0 中的快了好几倍(根据 List Hunter 回归测试
>> > 集的 benchmark 结果,前者为平均 60 ms,后者则长达 200+ ms)。(Firefox
>> > 3.1 中 TraceMonkey 的 JIT 支持倒并没有给 List Hunter 中的 JS 带来可测
>> > 量的性能提升。)
>> >
>> > 纯 JS 写的 Firefox 插件可以在 Win32/Linux/Mac 多种操作系统上即装即用,
>> > 所以方便和编辑及产品经理沟通行为细节,方便演示。如若计算过于复杂,亦可
>> > 使用 C++ 语言改写插件中的计算密集的部分。
>> >
>> > =item 缺点
>> >
>> > Firefox 是高耦合的软件,这与 Google Chrome 及 Safari 浏览器的核心
>> > Webkit 形成了鲜明对比。这意味着,我们比较难于对 Firefox 进行深层次的裁
>> > 剪,无法轻易地免除一些比较大的功能部件,也很难将其中的某一个大部件剥出
>> > 来单独使用(当然了,SpiderMonkey 是少数几个例外之一)。
>> >
>> > =back
>> >
>> > =head1 AUTHOR
>> >
>> > 章亦春 (agentzh) C<< <agentzh@yahoo.cn> >>
>> >
>> > =head1 LICENSE
>> >
>> > Copyright (c) 2007-2008, Yahoo! China EEEE Works, Alibaba Inc. All
>> > rights reserved.
>> >
>> > Redistribution and use in source and binary forms, with or without
>> > modification, are permitted provided that the following conditions are
>> > met:
>> >
>> > =over
>> >
>> > =item *
>> >
>> > Redistributions of source code must retain the above copyright notice,
>> > this list of conditions and the following disclaimer.
>> >
>> > =item *
>> >
>> > Redistributions in binary form must reproduce the above copyright
>> > notice, this list of conditions and the following disclaimer in the
>> > documentation and/or other materials provided with the distribution.
>> >
>> > =item *
>> >
>> > Neither the name of the Yahoo! China EEEE Works, Alibaba Inc. nor the
>> > names of its contributors may be used to endorse or promote products
>> > derived from this software without specific prior written permission.
>> >
>> > =back
>> >
>> > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> > "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> > LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> > A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> > OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> > SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> > LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> > DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> > THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> > (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> > OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> >
>> > _______________________________________________
>> > China-pm mailing list
>> > China-pm@pm.org
>> > http://mail.pm.org/mailman/listinfo/china-pm
>>
>> _______________________________________________
>> China-pm mailing list
>> China-pm@pm.org
>> http://mail.pm.org/mailman/listinfo/china-pm
>
> _______________________________________________
> China-pm mailing list
> China-pm@pm.org
> http://mail.pm.org/mailman/listinfo/china-pm

_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

刚刚发现错过了 infoQ 的一篇不错的文章。
http://www.infoq.com/cn/news/2008/12/CPAN-Win32

非常适合作为 CPAN 作者的圣诞节礼物 :)

On 四, 2008-12-25 at 21:58 +0800, Jacky Xu wrote:
> <--
> http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/
>
> Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的进
> 程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者当子
> 进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。Proc::Harness
> 脚本自身则是挂在了 deamontools 之下。 -->
>
> 貌似这个我有需求,监控进程,丢失后立刻重启
>
>
> 在 2008-12-25四的 15:13 +0800,agentzh写道:
> > 2008/12/25 wbi 畢 <wbisearchina@hotmail.co.jp>
> > >
> > > Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?
> >
> > =head1 NAME
> >
> > List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓
> > 爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。
> >
> > =head1 背景
> >
> > 在我们的生活搜索项目中,需要对网页进行深层次的识别和抽取。基于文本内容
> > 的分类我们目前采用的是美国雅虎基于最大熵的 DCP 系统。而对于网页结构方
> > 面的分类(即这个网页是列表页呢,还是详情页?),以及主体链接列表、主体
> > 区域抽取,则一直缺乏比较好的解决方案。我的同事尝试过通过纯粹的结构化的
> > 方法(如海维算法)进行识别,准确率只有 60%,而基于 SVM 这样的机器学习
> > 的方法,对网页类型比较敏感,如目标网页与训练集相差较多,则准确率迅速下
> > 降。
> >
> > 于是我尝试把网页显示时的视觉信息结合到海维算法以及块合并算法中。于是准
> > 确率和召回率分别达到了 90% 和 80%。这里的视觉信息主要包括一个网页区域
> > 的大小、形状、和在整个页面中的位置。更多的信息还包括字体、颜色等等。这
> > 样,便诞生了 List Hunter 插件。于是如何将 Firefox 插件做成一个大规模的
> > 集群用于生产,便成为了重要问题。
> >
> > 在下面这篇 blog 文章中我介绍了更多背景方面的细节以及 List Hunter 插件
> > 本身的情况:
> >
> > http://blog.agentzh.org/#post-97
> >
> > =head1 集群的结构
> >
> > 该集群由四大部分组成:纯 Firefox 集群,Apache + mod_proxy +
> > mod_disk_cache 集群,curl 预取器集群,和 OpenResty 集群。一共有十几台
> > 生产机"全职"或者"兼职"地参与了这个集群。下面逐一介绍一下哈:
> >
> > =over
> >
> > =item 纯 Firefox 集群
> >
> > 纯 Firefox 集群目前由 8 台 4 核的 redhat5 生产机组成。每台生产机运行 3
> > 个 Firefox 3.1 进程实例。因为那 8 台机器同时服务于淘宝 VIP 搜索的商口
> > 图片显示接口(大约 600 万日 PV),所以我们没敢在这些机器上运行比较多的
> > Firefox 进程。
> >
> > 需要指出的是,Firefox 默认是"进程复用"的运行方式。即启动多次
> > firefox-bin 可执行程序,其实得到的还是单个 Firefox 进程。这种进程复用
> > 方式无法充分利用生产机的多核 CPU。因为在任意给定时刻,一个进程只能跑在
> > 一个核上,哪怕它是多线程的。为了让 Firefox 以多进程方式运行,需要:
> >
> > =over
> >
> > =item 1.
> >
> > 在调用 firefox-bin 程序时指定 -no-remote 命令行选项,或者设置环境变量
> > MOZ_NO_REMOTE=1
> >
> > =item 2.
> >
> > 以不同的 profile 运行不同的 firefox-bin 进程(利用 -P 命令行选项)。
> >
> > =back
> >
> > 我们平常看到的 Firefox 的主窗口并不启动,而以 chrome 方式单独运行 List
> > Hunter 插件的界面,例如:
> >
> > firefox -chrome chrome://listhunter/content/crawler.xul -P
> > crawler2 -no-remote
> >
> > 以 chrome 方式运行的插件与 XULRunner 方式运行的 XUL 应用是很类似的。
> >
> > 由于 Firefox 3.1 还没有正式发布,我直接 checkout 官方 Mercurial 源码仓
> > 库内的最新版本,自己在我们的 redhat 生产机上编译的。我们目前几乎没有修
> > 改官方的 C++ 源代码,为了方便和官方版本保持同步。我们目前使用的是下面
> > 的 firefox 编译选项:
> >
> > # My .mozconfig
> > mk_add_options MOZ_MAKE_FLAGS="-j2"
> > mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
> > ac_add_options --enable-crypto --enable-feeds
> > --disable-profilesharing --enable-rdf --enable-zipwriter
> > --disable-tests --disable-gnomeui --disable-cookies --disable-canvas
> > --disable-gnomeui --disable-inspector-apis --disable-mailnews
> > --disable-mathml --disable-official-branding
> > --enable-plaintext-editor-only --disable-postscript --disable-printing
> > --disable-profilelocking --disable-safe-browsing
> > --disable-startup-notification --disable-svg
> > --disable-svg-foreignobject --disable-updater --disable-javaxpcom
> > --disable-plugins --disable-crashreporter --disable-tests
> > --disable-debug --enable-application=browser --build=i686-linux
> > --disable-jsd --disable-ldap --enable-strip --disable-accessibility
> > --disable-ogg --disable-dbus --disable-freetype2 --disable-optimize
> >
> > 这里能禁用的功能我们都禁用了,这里的 feeds, rdf, crypto 这三个都不能
> > disable,否则源码编译不通过,会报一些 .h 头文件找不到,呵
> > 呵。--disable-ogg 实际上也不起作用,但网上的材料看曾经有效过,呵呵。
> >
> > 事实上,目前我们还是给官方的源码打了一个 C++ 补丁,用于将 Error
> > Console 中的 Errors 重定向到 stderr,这样方便我们在集群环境下通过
> > Firefox 进程的 log 文件捕捉和诊断一些异常。目前的补丁是下面这个样子:
> >
> > http://agentzh.org/misc/191src.patch.txt
> >
> > 值得一提的是,Firefox 进程本身是"无头"的,即它运行在 Xvfb 这个 X
> > server 之上,只在内存里执行渲染,而不需要任何显示硬件的存在。这些
> > Firefox 进程本身是挂在我们自己的一个 Perl 写的进程监控脚本之下。该脚本
> > 来自我们的 Proc::Harness 模块:
> >
> >
> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/
> >
> > Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的
> > 进程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者
> > 当子进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。
> > Proc::Harness 脚本自身则是挂在了 deamontools 之下。
> >
> > 这些 Firefox 进程受安装在其中的 List Hunter 插件的完全控制。它们都是高
> > 度自治的 robot。它们内部有一个处理循环,一批一批地从 OpenResty 的 web
> > service 接口取到 URL 任务,然后一个一个地在 Firefox 的 browser 组件里
> > 加载和分析,最后把分析到的结果一批一批地通过 OpenResty 提交之。
> >
> > =item curl 预取爬虫集群与 Apache mod_proxy 集群
> >
> > 该集群目前布署了 6 台双核的 redhat4 生产机。每台机器都安装了两个集群组
> > 件,一是预取器,一是 Apache mod_proxy. 预取器的作用是通过 curl (准确
> > 地说是 WWW::Curl 模块)将网页的 HTML 和 CSS 通过 mod_proxy 预取一遍,
> > 这样这些请求的结果就可以在 mod_proxy 中通过 mod_disk_cache 缓存住。于
> > 是当纯 Firefox 集群再通过 mod_proxy 去抓这些 URL 时,mod_proxy 就可以
> > 直接把缓存后的结果直接返回给 Firefox 了。
> >
> > 预取器和 Firefox 进程是同时工作的,但对于一个 URL 任务而言,只有通过预
> > 取器预取过之后,Firefox 进程才会进行处理。所以实际构成了一个两道工序的
> > 流水线。这种调度是由 OpenResty 集群来完成的。
> >
> > 预取器目前是以一个叫为 WWW::Prefetcher 的 Perl 模块的形式来实现的:
> >
> >
> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/WWW-Prefetcher/
> >
> > 虽然 mod_cache 提供了许多选项,但其缓存行为还是比较遵守 RFC 的 cache
> > 要求的。因此我对 mod_cache 模块进行了许多修改,使之可以无条件地缓存住
> > 请求过的所有网页,而不论其 URL 是否有 querystring,也不论其 response
> > header 中的要求是什么。我们对最新的 httpd 2.2.11 的补丁如下:
> >
> > http://agentzh.org/misc/httpd-2.2.11.patch.txt
> >
> > 特别地,mod_disk_cache 指向的不是磁盘目录,而是 RAM 中开辟的 tmpfs 分
> > 区。由于我们这 6 台机器都是很旧的 IDE 硬盘,因此直接用磁盘作 cache 存
> > 储时,高并发条件下,每台机器的 load 都在 20 以上,根本无法忍受。后来换
> > 为 tmpfs 结果 htcacheclean 工具之后,机器负载就降到 0.1 以下了。
> >
> > =item OpenResty集群
> >
> > 由于 OpenResty 的通用性,我们直接复用了同时服务于 yahoo.cn 和口碑网的
> > 那个生产集群,(3 台 FastCGI 前端机和1 台 PL/Proxy 机器),所以我就没
> > 有布署新的机器。在服务于 Firefox 集群的 OpenResty 接口中通过 View API
> > 暴露了若干的 PostgreSQL 函数,以完成整个 List Hunter 集群的任务调度和
> > 结果汇总。目前的实现中,我们通过 Pg 的 sequence 摸拟了一种循环任务队
> > 列,并通过计数器完成流水线中两道工序之间的相对同步。
> >
> > 相关的 Pg 函数、sequence、以及索引的定义在这里:
> >
> >
> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-db.sql
> >
> > 相关的 OpenResty 对象的定义则在这里:
> >
> >
> > http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-resty.pl
> >
> > =back
> >
> > =head1 集群的性能
> >
> > 集群目前每小时的产出稳定在 10 万网页以上,一天的产出在 240 万以上。
> > Firefox 机器的负载在 3 左右,Proxy 的负载在 0.1 以下。
> >
> > JS 基准测试显示 Firefox 3.1 加载一个页面的平均延时是 200 ~ 300 ms,机
> > 房间的网络延时在 10 ~ 20 ms(因为网页已被 mod_cache 缓存住,故无到外网
> > 的网络开销), List Hunter 插件的 DOM 分析代码的用时在 200 ~ 300 ms。其
> > 他 OpenResty 开销再计入,大约 1 sec 处理一个页面。
> >
> > =head1 已知瓶颈和缺陷
> >
> > 当 OpenResty 中的 URL 任务表的行数超过 100 ~ 200 万时,调度查询容易超
> > 过 PL/Proxy 的 10 秒限制。因此,我们目前采取"流式"的任务导入和导出方
> > 式。通过 cronjob 定期地向库中导入任务,并同时把完成了的任务及时移出。
> >
> > Apache 的 mod_proxy 在高并发条件下不够稳定,而且限于 Apache 自身的体系
> > 结构,无法实现 proxy pipelining. 因此计划在未来集群规模进一步扩大时,
> > 改用 Squid. 当然了,Squid 很可能也需要进行修改才能满足我们这里的强制缓
> > 存一段指定时间的需求。
> >
> > 同时,受限于 Apache mod_cache 后端的非分布式,代理服务器的调度是在
> > Firefox 进程和 curl 预取进程中完成的,导致前端代码比较复杂,还带来了代
> > 理服务器列表的定时同步问题。因此,未来可以考虑为 Apache mod_cache 或者
> > Squid 添加 memcached 缓存后端的支持。这样代理前端的多台服务器可以实现
> > 对集群内其他部件的"透明化"。
> >
> > =head1 TODO
> >
> > =over
> >
> > =item 1.
> >
> > 换用 Squid + memcached 作为缓存用正向代理
> >
> > =item 2.
> >
> > 通过 XULRunner 而非 firefox -chrome 方式运行 List Hunter 插件。(需要
> > 为我的 XUL::App 框架添加 XULRunner 支持)
> >
> > =back
> >
> > =head1 与相似产品的异同
> >
> > 美国雅虎通过大量修改 Firefox 2 的 C++ 源代码,开发了叫为 HLFS 的爬虫集
> > 群,用于爬取 AJAX 网站的内容以及得到带有视觉信息的 DOM 树。他们将
> > Firefox 进程做成了 HTTP 代理的形式,对外部应用提供服务。
> >
> > 而我们的 List Hunter 集群中的 Firefox 进程则是高度自治的爬虫,它们自己
> > 从 OpenResty 中不断地批量取任务去完成。而外部应用则是批量地向
> > OpenResty 导入任务来让集群运转。由于 List Hunter 集群并没怎么修改
> > Firefox 的源代码,这使得我们可以很容易地与官方最新版本保持同步,从而第
> > 一时享受到官方优化带来的众多好处。
> >
> > 同时 List Hunter 集群本身是通用目的的,它可以作为各种 Firefox 插件
> > 的"集群容器"。换言之,这是一种将 Firefox 插件"集群化"的完整的框架。
> >
> > 由于 Firefox 插件开发本身已经通过我发布到 CPAN 的 XUL::App 框架得到了
> > 极大的简化,所以响应新的需求的成本是非常低的。
> >
> > =head1 使用 Firefox 的利与弊
> >
> > =over
> >
> > =item 优点
> >
> > Firefox 是世界级的浏览器。作为最复杂功能最丰富的 Internet 客户端之一,
> > 我们将之作为爬虫可以享受到和最终用户一样的丰富功能,无论是 AJAX 还是视
> > 觉信息都不是问题。
> >
> > Firefox 有基于 XUL 和 chrome JS 的灵活的插件机制,极易扩展。事实上,
> > Firefox 主界面自身就是一个大插件。同时,Gecko 是基于 XPCOM 组件方式
> > 的,因此可以很容易地使用 C/C++/Java 等语言开发 XPCOM 组件,然后再用
> > JavaSscript 把它们粘合在一起。于是乎,JavaScript 成为了像 Perl 一样的
> > 胶水类语言。
> >
> > 运行于 Gecko 之上的插件 JavaScript 拥有最高权限,这种 JS 可以访问磁盘
> > 文件,可以访问系统环境变量,可以使用原生的 XmlHttpRequest 对象发出跨域
> > AJAX 请求。
> >
> > Firefox 的性能随着新版本的发布总会有戏剧性的变化。Firefox 3.1 中的
> > Gecko 引擎的渲染速度就比 3.0 中的快了好几倍(根据 List Hunter 回归测试
> > 集的 benchmark 结果,前者为平均 60 ms,后者则长达 200+ ms)。(Firefox
> > 3.1 中 TraceMonkey 的 JIT 支持倒并没有给 List Hunter 中的 JS 带来可测
> > 量的性能提升。)
> >
> > 纯 JS 写的 Firefox 插件可以在 Win32/Linux/Mac 多种操作系统上即装即用,
> > 所以方便和编辑及产品经理沟通行为细节,方便演示。如若计算过于复杂,亦可
> > 使用 C++ 语言改写插件中的计算密集的部分。
> >
> > =item 缺点
> >
> > Firefox 是高耦合的软件,这与 Google Chrome 及 Safari 浏览器的核心
> > Webkit 形成了鲜明对比。这意味着,我们比较难于对 Firefox 进行深层次的裁
> > 剪,无法轻易地免除一些比较大的功能部件,也很难将其中的某一个大部件剥出
> > 来单独使用(当然了,SpiderMonkey 是少数几个例外之一)。
> >
> > =back
> >
> > =head1 AUTHOR
> >
> > 章亦春 (agentzh) C<< <agentzh@yahoo.cn> >>
> >
> > =head1 LICENSE
> >
> > Copyright (c) 2007-2008, Yahoo! China EEEE Works, Alibaba Inc. All
> > rights reserved.
> >
> > Redistribution and use in source and binary forms, with or without
> > modification, are permitted provided that the following conditions are
> > met:
> >
> > =over
> >
> > =item *
> >
> > Redistributions of source code must retain the above copyright notice,
> > this list of conditions and the following disclaimer.
> >
> > =item *
> >
> > Redistributions in binary form must reproduce the above copyright
> > notice, this list of conditions and the following disclaimer in the
> > documentation and/or other materials provided with the distribution.
> >
> > =item *
> >
> > Neither the name of the Yahoo! China EEEE Works, Alibaba Inc. nor the
> > names of its contributors may be used to endorse or promote products
> > derived from this software without specific prior written permission.
> >
> > =back
> >
> > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> >
> > _______________________________________________
> > China-pm mailing list
> > China-pm@pm.org
> > http://mail.pm.org/mailman/listinfo/china-pm
>
> _______________________________________________
> China-pm mailing list
> China-pm@pm.org
> http://mail.pm.org/mailman/listinfo/china-pm

_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

2008年12月25日星期四

[PerlChina] Greeting from Freeborders

Hi,
 
I hope this message finds you well. 
 
This is Fancy from Freeborders recruiting team.  We are interviewing to hire a Sr. Lamp Engineer in Shenzhen

Feeborders is one of the fastest growing firms in the leading provider of technology solutions and outsourcing from China; "Top five to watch in China, 2006" and "Top Ten to Watch in Asia, 2007". We received an Outsourcing Excellence Award from Forbes Magazine 2006. We were also named one of the world's 50 best managed vendors by "The Black Book of Outsourcing."

Freeborders is headquartered in San Francisco with project team locations in Europe, Asia & US. We have offices in San Francisco, New York, Hong Kong, Shenzhen and Montreal.

We offer a competitive compensation, paid vacations,  and employee health benefits. Great career advance opportunities.
 
Pls call or email me back if any interest. My msn is yanjing112@hotmail.com
 
 

Sr. LAMP Engineer

 

Familiar with design patterns

Over 4 years Web Development experience

Strong Linux, Apache, MySql, and Perl (PHP) experience

- Understanding of request / response phase processing

- Practical experience with MVC architecture

- Hands-on experience developing highly-scalable, multi-tiered web sites

- HTML, CSS, Javascript, DHTML, JSON and AJAX skills required

- Ability to debug complex web applications in a distributed environment

- Familiar with browser compatibility issues

- Willing to learn Perl is a requirement

Linux and Open Source Technologies

- Good working knowledge of GNU/Linux and other Open Source technologies

- Apache Web Server (mod_perl a huge plus)

- MySQL 5.x Series

Familiarity with RDBMS

- Understanding of ACID compliance

- Stored Procedures

- Dynamic SQL generation

- MySQL and Oracle a plus

Service Oriented Architecture

- Knowledge of SOA and its applications

- SOAP, WSDL, XMLRPC

Software Development Process

- At least 3 years experience with any major software development methodology

- Easily comprehend design and architecture documents

- Ability to write clear documentation

- Experience with cross-site development

General Skills

- Ability to learn quickly and think on your feet

- Willing to learn new or unfamiliar programming languages and technologies

    - Excellent communication skills

 

 

Fancy   Yan
Recruiting Specialist

Freeborders
10/F, Sci. & Tech. Park Building

No.6, Keyuan Road, Sci. & Tech

Industry Park, Nanshan District,
Shenzhen, China 518057

office: (86)(755) 26504678

fax: (86)(755) 26504768
fancy.yan@freeborders.com

www.freeborders.com

Re: [PerlChina] 请问有什么便捷的方法载入zip包里的库?

呵呵,用 PAR 应该满足你的要求,只是不知道你的服务器空间是否有 PAR,或者支持自己安装 PAR 模块

2008/12/25 agentzh <agentzh@gmail.com>
2008/12/25 Luo Yong <luo.yong.name@gmail.com>
多谢,

这个方法大概是最好的方法了,不过感觉Java的那种用JAR文件封装类库的方法很方便,但是在perl上暂时没办法实现,不知道perl6里有没有类似的功能。


CPAN 上有一个叫做 pp 的工具可以把 Perl 5 类库封成 PAR 文件 ;)

基于 parrot 的 Perl 6 中可以在字节码级别进行联编,就更方便了 ;)

-agentzh

_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

<--
http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/

Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的进
程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者当子
进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。Proc::Harness
脚本自身则是挂在了 deamontools 之下。 -->

貌似这个我有需求,监控进程,丢失后立刻重启


在 2008-12-25四的 15:13 +0800,agentzh写道:
> 2008/12/25 wbi 畢 <wbisearchina@hotmail.co.jp>
> >
> > Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?
>
> =head1 NAME
>
> List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓
> 爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。
>
> =head1 背景
>
> 在我们的生活搜索项目中,需要对网页进行深层次的识别和抽取。基于文本内容
> 的分类我们目前采用的是美国雅虎基于最大熵的 DCP 系统。而对于网页结构方
> 面的分类(即这个网页是列表页呢,还是详情页?),以及主体链接列表、主体
> 区域抽取,则一直缺乏比较好的解决方案。我的同事尝试过通过纯粹的结构化的
> 方法(如海维算法)进行识别,准确率只有 60%,而基于 SVM 这样的机器学习
> 的方法,对网页类型比较敏感,如目标网页与训练集相差较多,则准确率迅速下
> 降。
>
> 于是我尝试把网页显示时的视觉信息结合到海维算法以及块合并算法中。于是准
> 确率和召回率分别达到了 90% 和 80%。这里的视觉信息主要包括一个网页区域
> 的大小、形状、和在整个页面中的位置。更多的信息还包括字体、颜色等等。这
> 样,便诞生了 List Hunter 插件。于是如何将 Firefox 插件做成一个大规模的
> 集群用于生产,便成为了重要问题。
>
> 在下面这篇 blog 文章中我介绍了更多背景方面的细节以及 List Hunter 插件
> 本身的情况:
>
> http://blog.agentzh.org/#post-97
>
> =head1 集群的结构
>
> 该集群由四大部分组成:纯 Firefox 集群,Apache + mod_proxy +
> mod_disk_cache 集群,curl 预取器集群,和 OpenResty 集群。一共有十几台
> 生产机"全职"或者"兼职"地参与了这个集群。下面逐一介绍一下哈:
>
> =over
>
> =item 纯 Firefox 集群
>
> 纯 Firefox 集群目前由 8 台 4 核的 redhat5 生产机组成。每台生产机运行 3
> 个 Firefox 3.1 进程实例。因为那 8 台机器同时服务于淘宝 VIP 搜索的商口
> 图片显示接口(大约 600 万日 PV),所以我们没敢在这些机器上运行比较多的
> Firefox 进程。
>
> 需要指出的是,Firefox 默认是"进程复用"的运行方式。即启动多次
> firefox-bin 可执行程序,其实得到的还是单个 Firefox 进程。这种进程复用
> 方式无法充分利用生产机的多核 CPU。因为在任意给定时刻,一个进程只能跑在
> 一个核上,哪怕它是多线程的。为了让 Firefox 以多进程方式运行,需要:
>
> =over
>
> =item 1.
>
> 在调用 firefox-bin 程序时指定 -no-remote 命令行选项,或者设置环境变量
> MOZ_NO_REMOTE=1
>
> =item 2.
>
> 以不同的 profile 运行不同的 firefox-bin 进程(利用 -P 命令行选项)。
>
> =back
>
> 我们平常看到的 Firefox 的主窗口并不启动,而以 chrome 方式单独运行 List
> Hunter 插件的界面,例如:
>
> firefox -chrome chrome://listhunter/content/crawler.xul -P
> crawler2 -no-remote
>
> 以 chrome 方式运行的插件与 XULRunner 方式运行的 XUL 应用是很类似的。
>
> 由于 Firefox 3.1 还没有正式发布,我直接 checkout 官方 Mercurial 源码仓
> 库内的最新版本,自己在我们的 redhat 生产机上编译的。我们目前几乎没有修
> 改官方的 C++ 源代码,为了方便和官方版本保持同步。我们目前使用的是下面
> 的 firefox 编译选项:
>
> # My .mozconfig
> mk_add_options MOZ_MAKE_FLAGS="-j2"
> mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
> ac_add_options --enable-crypto --enable-feeds
> --disable-profilesharing --enable-rdf --enable-zipwriter
> --disable-tests --disable-gnomeui --disable-cookies --disable-canvas
> --disable-gnomeui --disable-inspector-apis --disable-mailnews
> --disable-mathml --disable-official-branding
> --enable-plaintext-editor-only --disable-postscript --disable-printing
> --disable-profilelocking --disable-safe-browsing
> --disable-startup-notification --disable-svg
> --disable-svg-foreignobject --disable-updater --disable-javaxpcom
> --disable-plugins --disable-crashreporter --disable-tests
> --disable-debug --enable-application=browser --build=i686-linux
> --disable-jsd --disable-ldap --enable-strip --disable-accessibility
> --disable-ogg --disable-dbus --disable-freetype2 --disable-optimize
>
> 这里能禁用的功能我们都禁用了,这里的 feeds, rdf, crypto 这三个都不能
> disable,否则源码编译不通过,会报一些 .h 头文件找不到,呵
> 呵。--disable-ogg 实际上也不起作用,但网上的材料看曾经有效过,呵呵。
>
> 事实上,目前我们还是给官方的源码打了一个 C++ 补丁,用于将 Error
> Console 中的 Errors 重定向到 stderr,这样方便我们在集群环境下通过
> Firefox 进程的 log 文件捕捉和诊断一些异常。目前的补丁是下面这个样子:
>
> http://agentzh.org/misc/191src.patch.txt
>
> 值得一提的是,Firefox 进程本身是"无头"的,即它运行在 Xvfb 这个 X
> server 之上,只在内存里执行渲染,而不需要任何显示硬件的存在。这些
> Firefox 进程本身是挂在我们自己的一个 Perl 写的进程监控脚本之下。该脚本
> 来自我们的 Proc::Harness 模块:
>
>
> http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/
>
> Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的
> 进程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者
> 当子进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。
> Proc::Harness 脚本自身则是挂在了 deamontools 之下。
>
> 这些 Firefox 进程受安装在其中的 List Hunter 插件的完全控制。它们都是高
> 度自治的 robot。它们内部有一个处理循环,一批一批地从 OpenResty 的 web
> service 接口取到 URL 任务,然后一个一个地在 Firefox 的 browser 组件里
> 加载和分析,最后把分析到的结果一批一批地通过 OpenResty 提交之。
>
> =item curl 预取爬虫集群与 Apache mod_proxy 集群
>
> 该集群目前布署了 6 台双核的 redhat4 生产机。每台机器都安装了两个集群组
> 件,一是预取器,一是 Apache mod_proxy. 预取器的作用是通过 curl (准确
> 地说是 WWW::Curl 模块)将网页的 HTML 和 CSS 通过 mod_proxy 预取一遍,
> 这样这些请求的结果就可以在 mod_proxy 中通过 mod_disk_cache 缓存住。于
> 是当纯 Firefox 集群再通过 mod_proxy 去抓这些 URL 时,mod_proxy 就可以
> 直接把缓存后的结果直接返回给 Firefox 了。
>
> 预取器和 Firefox 进程是同时工作的,但对于一个 URL 任务而言,只有通过预
> 取器预取过之后,Firefox 进程才会进行处理。所以实际构成了一个两道工序的
> 流水线。这种调度是由 OpenResty 集群来完成的。
>
> 预取器目前是以一个叫为 WWW::Prefetcher 的 Perl 模块的形式来实现的:
>
>
> http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/WWW-Prefetcher/
>
> 虽然 mod_cache 提供了许多选项,但其缓存行为还是比较遵守 RFC 的 cache
> 要求的。因此我对 mod_cache 模块进行了许多修改,使之可以无条件地缓存住
> 请求过的所有网页,而不论其 URL 是否有 querystring,也不论其 response
> header 中的要求是什么。我们对最新的 httpd 2.2.11 的补丁如下:
>
> http://agentzh.org/misc/httpd-2.2.11.patch.txt
>
> 特别地,mod_disk_cache 指向的不是磁盘目录,而是 RAM 中开辟的 tmpfs 分
> 区。由于我们这 6 台机器都是很旧的 IDE 硬盘,因此直接用磁盘作 cache 存
> 储时,高并发条件下,每台机器的 load 都在 20 以上,根本无法忍受。后来换
> 为 tmpfs 结果 htcacheclean 工具之后,机器负载就降到 0.1 以下了。
>
> =item OpenResty集群
>
> 由于 OpenResty 的通用性,我们直接复用了同时服务于 yahoo.cn 和口碑网的
> 那个生产集群,(3 台 FastCGI 前端机和1 台 PL/Proxy 机器),所以我就没
> 有布署新的机器。在服务于 Firefox 集群的 OpenResty 接口中通过 View API
> 暴露了若干的 PostgreSQL 函数,以完成整个 List Hunter 集群的任务调度和
> 结果汇总。目前的实现中,我们通过 Pg 的 sequence 摸拟了一种循环任务队
> 列,并通过计数器完成流水线中两道工序之间的相对同步。
>
> 相关的 Pg 函数、sequence、以及索引的定义在这里:
>
>
> http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-db.sql
>
> 相关的 OpenResty 对象的定义则在这里:
>
>
> http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-resty.pl
>
> =back
>
> =head1 集群的性能
>
> 集群目前每小时的产出稳定在 10 万网页以上,一天的产出在 240 万以上。
> Firefox 机器的负载在 3 左右,Proxy 的负载在 0.1 以下。
>
> JS 基准测试显示 Firefox 3.1 加载一个页面的平均延时是 200 ~ 300 ms,机
> 房间的网络延时在 10 ~ 20 ms(因为网页已被 mod_cache 缓存住,故无到外网
> 的网络开销), List Hunter 插件的 DOM 分析代码的用时在 200 ~ 300 ms。其
> 他 OpenResty 开销再计入,大约 1 sec 处理一个页面。
>
> =head1 已知瓶颈和缺陷
>
> 当 OpenResty 中的 URL 任务表的行数超过 100 ~ 200 万时,调度查询容易超
> 过 PL/Proxy 的 10 秒限制。因此,我们目前采取"流式"的任务导入和导出方
> 式。通过 cronjob 定期地向库中导入任务,并同时把完成了的任务及时移出。
>
> Apache 的 mod_proxy 在高并发条件下不够稳定,而且限于 Apache 自身的体系
> 结构,无法实现 proxy pipelining. 因此计划在未来集群规模进一步扩大时,
> 改用 Squid. 当然了,Squid 很可能也需要进行修改才能满足我们这里的强制缓
> 存一段指定时间的需求。
>
> 同时,受限于 Apache mod_cache 后端的非分布式,代理服务器的调度是在
> Firefox 进程和 curl 预取进程中完成的,导致前端代码比较复杂,还带来了代
> 理服务器列表的定时同步问题。因此,未来可以考虑为 Apache mod_cache 或者
> Squid 添加 memcached 缓存后端的支持。这样代理前端的多台服务器可以实现
> 对集群内其他部件的"透明化"。
>
> =head1 TODO
>
> =over
>
> =item 1.
>
> 换用 Squid + memcached 作为缓存用正向代理
>
> =item 2.
>
> 通过 XULRunner 而非 firefox -chrome 方式运行 List Hunter 插件。(需要
> 为我的 XUL::App 框架添加 XULRunner 支持)
>
> =back
>
> =head1 与相似产品的异同
>
> 美国雅虎通过大量修改 Firefox 2 的 C++ 源代码,开发了叫为 HLFS 的爬虫集
> 群,用于爬取 AJAX 网站的内容以及得到带有视觉信息的 DOM 树。他们将
> Firefox 进程做成了 HTTP 代理的形式,对外部应用提供服务。
>
> 而我们的 List Hunter 集群中的 Firefox 进程则是高度自治的爬虫,它们自己
> 从 OpenResty 中不断地批量取任务去完成。而外部应用则是批量地向
> OpenResty 导入任务来让集群运转。由于 List Hunter 集群并没怎么修改
> Firefox 的源代码,这使得我们可以很容易地与官方最新版本保持同步,从而第
> 一时享受到官方优化带来的众多好处。
>
> 同时 List Hunter 集群本身是通用目的的,它可以作为各种 Firefox 插件
> 的"集群容器"。换言之,这是一种将 Firefox 插件"集群化"的完整的框架。
>
> 由于 Firefox 插件开发本身已经通过我发布到 CPAN 的 XUL::App 框架得到了
> 极大的简化,所以响应新的需求的成本是非常低的。
>
> =head1 使用 Firefox 的利与弊
>
> =over
>
> =item 优点
>
> Firefox 是世界级的浏览器。作为最复杂功能最丰富的 Internet 客户端之一,
> 我们将之作为爬虫可以享受到和最终用户一样的丰富功能,无论是 AJAX 还是视
> 觉信息都不是问题。
>
> Firefox 有基于 XUL 和 chrome JS 的灵活的插件机制,极易扩展。事实上,
> Firefox 主界面自身就是一个大插件。同时,Gecko 是基于 XPCOM 组件方式
> 的,因此可以很容易地使用 C/C++/Java 等语言开发 XPCOM 组件,然后再用
> JavaSscript 把它们粘合在一起。于是乎,JavaScript 成为了像 Perl 一样的
> 胶水类语言。
>
> 运行于 Gecko 之上的插件 JavaScript 拥有最高权限,这种 JS 可以访问磁盘
> 文件,可以访问系统环境变量,可以使用原生的 XmlHttpRequest 对象发出跨域
> AJAX 请求。
>
> Firefox 的性能随着新版本的发布总会有戏剧性的变化。Firefox 3.1 中的
> Gecko 引擎的渲染速度就比 3.0 中的快了好几倍(根据 List Hunter 回归测试
> 集的 benchmark 结果,前者为平均 60 ms,后者则长达 200+ ms)。(Firefox
> 3.1 中 TraceMonkey 的 JIT 支持倒并没有给 List Hunter 中的 JS 带来可测
> 量的性能提升。)
>
> 纯 JS 写的 Firefox 插件可以在 Win32/Linux/Mac 多种操作系统上即装即用,
> 所以方便和编辑及产品经理沟通行为细节,方便演示。如若计算过于复杂,亦可
> 使用 C++ 语言改写插件中的计算密集的部分。
>
> =item 缺点
>
> Firefox 是高耦合的软件,这与 Google Chrome 及 Safari 浏览器的核心
> Webkit 形成了鲜明对比。这意味着,我们比较难于对 Firefox 进行深层次的裁
> 剪,无法轻易地免除一些比较大的功能部件,也很难将其中的某一个大部件剥出
> 来单独使用(当然了,SpiderMonkey 是少数几个例外之一)。
>
> =back
>
> =head1 AUTHOR
>
> 章亦春 (agentzh) C<< <agentzh@yahoo.cn> >>
>
> =head1 LICENSE
>
> Copyright (c) 2007-2008, Yahoo! China EEEE Works, Alibaba Inc. All
> rights reserved.
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are
> met:
>
> =over
>
> =item *
>
> Redistributions of source code must retain the above copyright notice,
> this list of conditions and the following disclaimer.
>
> =item *
>
> Redistributions in binary form must reproduce the above copyright
> notice, this list of conditions and the following disclaimer in the
> documentation and/or other materials provided with the distribution.
>
> =item *
>
> Neither the name of the Yahoo! China EEEE Works, Alibaba Inc. nor the
> names of its contributors may be used to endorse or promote products
> derived from this software without specific prior written permission.
>
> =back
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
> _______________________________________________
> China-pm mailing list
> China-pm@pm.org
> http://mail.pm.org/mailman/listinfo/china-pm

_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

2008/12/25 Question <wanliyou@gmail.com>:
>
> 推荐您看看这个:
> https://developer.mozilla.org/web-tech/2008/10/13/mozafterpaint/
> 一步步跟下去就有精彩的了,我记得有个extension有相关代码,不记得名字了,可以挖出来看看,不会很复杂的.
>

Wow. It's awesome! MAN!!!

THANKS!!!

We'll definitely abuse it!

-agentzh
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!



2008/12/25 agentzh <agentzh@gmail.com>
2008/12/25 Question <wanliyou@gmail.com>:
> 看得非常过瘾啊,对Yahoo有了新认识 :-)

谢谢 :)

> 关于使用firefox3.1,我建议你们可以试一下fennec里自带的xulrunner,应该是1.9.2a1/2pre的,可能比3.1好一点?

嗯,我会试一下的,只要它足够稳定就上生产,呵呵

> 你们的分析是建立在DOM树的基础上?不知道你们的应用有没有根据重绘来判断页面热点或者类似的?

我不太了解这里的"重绘"方法,能否介绍一下?谢谢!

推荐您看看这个:
https://developer.mozilla.org/web-tech/2008/10/13/mozafterpaint/
一步步跟下去就有精彩的了,我记得有个extension有相关代码,不记得名字了,可以挖出来看看,不会很复杂的.



> JIT可能没有打开chrome/content?

当然在 about:config 中都打开了,呵呵

> 没有完全咬文嚼字看完,回去再拜读!
>

客气!

Thanks!
-agentzh
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm



--
>: ~

Re: [PerlChina] 答复: 各位圣诞快乐哦!

2008/12/25 Question <wanliyou@gmail.com>:
> 看得非常过瘾啊,对Yahoo有了新认识 :-)

谢谢 :)

> 关于使用firefox3.1,我建议你们可以试一下fennec里自带的xulrunner,应该是1.9.2a1/2pre的,可能比3.1好一点?

嗯,我会试一下的,只要它足够稳定就上生产,呵呵

> 你们的分析是建立在DOM树的基础上?不知道你们的应用有没有根据重绘来判断页面热点或者类似的?

我不太了解这里的"重绘"方法,能否介绍一下?谢谢!

> JIT可能没有打开chrome/content?

当然在 about:config 中都打开了,呵呵

> 没有完全咬文嚼字看完,回去再拜读!
>

客气!

Thanks!
-agentzh
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

2008/12/25 wbi 畢 <wbisearchina@hotmail.co.jp>
>
> 您太客气了 我水平有限 很多地方没能理解 但是收获不小 非常感谢
> ________________________________

呵呵,纠正一处笔误:

"因为在任意给定时刻,一个进程只能跑在一个核上,哪怕它是多线程的"

应作

"因为在任意给定时刻,一个 firefox 进程(哪怕有多个窗口里的 JS 在同时打满运行)只能跑在一个核上,因为它不是多 OS 线程的"

-agentzh
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

看得非常过瘾啊,对Yahoo有了新认识 :-)
关于使用firefox3.1,我建议你们可以试一下fennec里自带的xulrunner,应该是1.9.2a1/2pre的,可能比3.1好一点?
你们的分析是建立在DOM树的基础上?不知道你们的应用有没有根据重绘来判断页面热点或者类似的?
JIT可能没有打开chrome/content?
没有完全咬文嚼字看完,回去再拜读!


2008/12/25 agentzh <agentzh@gmail.com>
2008/12/25 wbi � <wbisearchina@hotmail.co.jp>
>
>  Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?

=head1 NAME

List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。

=head1 背景

在我们的生活搜索项目中,需要对网页进行深层次的识别和抽取。基于文本内容的分类我们目前采用的是美国雅虎基于最大熵的 DCP 系统。而对于网页结构方面的分类(即这个网页是列表页呢,还是详情页?),以及主体链接列表、主体区域抽取,则一直缺乏比较好的解决方案。我的同事尝试过通过纯粹的结构化的方法(如海维算法)进行识别,准确率只有 60%,而基于 SVM 这样的机器学习的方法,对网页类型比较敏感,如目标网页与训练集相差较多,则准确率迅速下降。

于是我尝试把网页显示时的视觉信息结合到海维算法以及块合并算法中。于是准确率和召回率分别达到了 90% 和 80%。这里的视觉信息主要包括一个网页区域的大小、形状、和在整个页面中的位置。更多的信息还包括字体、颜色等等。这样,便诞生了 List Hunter 插件。于是如何将 Firefox 插件做成一个大规模的集群用于生产,便成为了重要问题。

在下面这篇 blog 文章中我介绍了更多背景方面的细节以及 List Hunter 插件本身的情况:

    http://blog.agentzh.org/#post-97

=head1 集群的结构

该集群由四大部分组成:纯 Firefox 集群,Apache + mod_proxy + mod_disk_cache 集群,curl 预取器集群,和 OpenResty 集群。一共有十几台生产机"全职"或者"兼职"地参与了这个集群。下面逐一介绍一下哈:

=over

=item 纯 Firefox 集群

纯 Firefox 集群目前由 8 台 4 核的 redhat5 生产机组成。每台生产机运行 3 个 Firefox 3.1 进程实例。因为那 8 台机器同时服务于淘宝 VIP 搜索的商口图片显示接口(大约 600 万日 PV),所以我们没敢在这些机器上运行比较多的 Firefox 进程。

需要指出的是,Firefox 默认是"进程复用"的运行方式。即启动多次 firefox-bin 可执行程序,其实得到的还是单个 Firefox 进程。这种进程复用方式无法充分利用生产机的多核 CPU。因为在任意给定时刻,一个进程只能跑在一个核上,哪怕它是多线程的。为了让 Firefox 以多进程方式运行,需要:

=over

=item 1.

在调用 firefox-bin 程序时指定 -no-remote 命令行选项,或者设置环境变量 MOZ_NO_REMOTE=1

=item 2.

以不同的 profile 运行不同的 firefox-bin 进程(利用 -P 命令行选项)。

=back

我们平常看到的 Firefox 的主窗口并不启动,而以 chrome 方式单独运行 List Hunter 插件的界面,例如:

    firefox -chrome chrome://listhunter/content/crawler.xul -P crawler2 -no-remote

以 chrome 方式运行的插件与 XULRunner 方式运行的 XUL 应用是很类似的。

由于 Firefox 3.1 还没有正式发布,我直接 checkout 官方 Mercurial 源码仓库内的最新版本,自己在我们的 redhat 生产机上编译的。我们目前几乎没有修改官方的 C++ 源代码,为了方便和官方版本保持同步。我们目前使用的是下面的 firefox 编译选项:

  # My .mozconfig
  mk_add_options MOZ_MAKE_FLAGS="-j2"
  mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
  ac_add_options --enable-crypto --enable-feeds --disable-profilesharing --enable-rdf --enable-zipwriter --disable-tests --disable-gnomeui --disable-cookies --disable-canvas --disable-gnomeui --disable-inspector-apis --disable-mailnews --disable-mathml --disable-official-branding --enable-plaintext-editor-only --disable-postscript --disable-printing --disable-profilelocking --disable-safe-browsing --disable-startup-notification --disable-svg --disable-svg-foreignobject --disable-updater --disable-javaxpcom --disable-plugins --disable-crashreporter --disable-tests --disable-debug --enable-application=browser --build=i686-linux --disable-jsd --disable-ldap --enable-strip --disable-accessibility --disable-ogg --disable-dbus --disable-freetype2 --disable-optimize

这里能禁用的功能我们都禁用了,这里的 feeds, rdf, crypto 这三个都不能 disable,否则源码编译不通过,会报一些 .h 头文件找不到,呵呵。--disable-ogg 实际上也不起作用,但网上的材料看曾经有效过,呵呵。

事实上,目前我们还是给官方的源码打了一个 C++ 补丁,用于将 Error Console 中的 Errors 重定向到 stderr,这样方便我们在集群环境下通过 Firefox 进程的 log 文件捕捉和诊断一些异常。目前的补丁是下面这个样子:

    http://agentzh.org/misc/191src.patch.txt

值得一提的是,Firefox 进程本身是"无头"的,即它运行在 Xvfb 这个 X server 之上,只在内存里执行渲染,而不需要任何显示硬件的存在。这些 Firefox 进程本身是挂在我们自己的一个 Perl 写的进程监控脚本之下。该脚本来自我们的 Proc::Harness 模块:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/

Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的进程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者当子进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。Proc::Harness 脚本自身则是挂在了 deamontools 之下。

这些 Firefox 进程受安装在其中的 List Hunter 插件的完全控制。它们都是高度自治的 robot。它们内部有一个处理循环,一批一批地从 OpenResty 的 web service 接口取到 URL 任务,然后一个一个地在 Firefox 的 browser 组件里加载和分析,最后把分析到的结果一批一批地通过 OpenResty 提交之。

=item curl 预取爬虫集群与 Apache mod_proxy 集群

该集群目前布署了 6 台双核的 redhat4 生产机。每台机器都安装了两个集群组件,一是预取器,一是 Apache mod_proxy. 预取器的作用是通过 curl (准确地说是 WWW::Curl 模块)将网页的 HTML 和 CSS 通过 mod_proxy 预取一遍,这样这些请求的结果就可以在 mod_proxy 中通过 mod_disk_cache 缓存住。于是当纯 Firefox 集群再通过 mod_proxy 去抓这些 URL 时,mod_proxy 就可以直接把缓存后的结果直接返回给 Firefox 了。

预取器和 Firefox 进程是同时工作的,但对于一个 URL 任务而言,只有通过预取器预取过之后,Firefox 进程才会进行处理。所以实际构成了一个两道工序的流水线。这种调度是由 OpenResty 集群来完成的。

预取器目前是以一个叫为 WWW::Prefetcher 的 Perl 模块的形式来实现的:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/WWW-Prefetcher/

虽然 mod_cache 提供了许多选项,但其缓存行为还是比较遵守 RFC 的 cache 要求的。因此我对 mod_cache 模块进行了许多修改,使之可以无条件地缓存住请求过的所有网页,而不论其 URL 是否有 querystring,也不论其 response header 中的要求是什么。我们对最新的 httpd 2.2.11 的补丁如下:

    http://agentzh.org/misc/httpd-2.2.11.patch.txt

特别地,mod_disk_cache 指向的不是磁盘目录,而是 RAM 中开辟的 tmpfs 分区。由于我们这 6 台机器都是很旧的 IDE 硬盘,因此直接用磁盘作 cache 存储时,高并发条件下,每台机器的 load 都在 20 以上,根本无法忍受。后来换为 tmpfs 结果 htcacheclean 工具之后,机器负载就降到 0.1 以下了。

=item OpenResty集群

由于 OpenResty 的通用性,我们直接复用了同时服务于 yahoo.cn 和口碑网的那个生产集群,(3 台 FastCGI 前端机和1 台 PL/Proxy 机器),所以我就没有布署新的机器。在服务于 Firefox 集群的 OpenResty 接口中通过 View API 暴露了若干的 PostgreSQL 函数,以完成整个 List Hunter 集群的任务调度和结果汇总。目前的实现中,我们通过 Pg 的 sequence 摸拟了一种循环任务队列,并通过计数器完成流水线中两道工序之间的相对同步。

相关的 Pg 函数、sequence、以及索引的定义在这里:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-db.sql

相关的 OpenResty 对象的定义则在这里:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-resty.pl

=back

=head1 集群的性能

集群目前每小时的产出稳定在 10 万网页以上,一天的产出在 240 万以上。Firefox 机器的负载在 3 左右,Proxy 的负载在 0.1 以下。

JS 基准测试显示 Firefox 3.1 加载一个页面的平均延时是 200 ~ 300 ms,机房间的网络延时在 10 ~ 20 ms(因为网页已被 mod_cache 缓存住,故无到外网的网络开销), List Hunter 插件的 DOM 分析代码的用时在 200 ~ 300 ms。其他 OpenResty 开销再计入,大约 1 sec 处理一个页面。

=head1 已知瓶颈和缺陷

当 OpenResty 中的 URL 任务表的行数超过 100 ~ 200 万时,调度查询容易超过 PL/Proxy 的 10 秒限制。因此,我们目前采取"流式"的任务导入和导出方式。通过 cronjob 定期地向库中导入任务,并同时把完成了的任务及时移出。

Apache 的 mod_proxy 在高并发条件下不够稳定,而且限于 Apache 自身的体系结构,无法实现 proxy pipelining. 因此计划在未来集群规模进一步扩大时,改用 Squid. 当然了,Squid 很可能也需要进行修改才能满足我们这里的强制缓存一段指定时间的需求。

同时,受限于 Apache mod_cache 后端的非分布式,代理服务器的调度是在 Firefox 进程和 curl 预取进程中完成的,导致前端代码比较复杂,还带来了代理服务器列表的定时同步问题。因此,未来可以考虑为 Apache mod_cache 或者 Squid 添加 memcached 缓存后端的支持。这样代理前端的多台服务器可以实现对集群内其他部件的"透明化"。

=head1 TODO

=over

=item 1.

换用 Squid + memcached 作为缓存用正向代理

=item 2.

通过 XULRunner 而非 firefox -chrome 方式运行 List Hunter 插件。(需要为我的 XUL::App 框架添加 XULRunner 支持)

=back

=head1 与相似产品的异同

美国雅虎通过大量修改 Firefox 2 的 C++ 源代码,开发了叫为 HLFS 的爬虫集群,用于爬取 AJAX 网站的内容以及得到带有视觉信息的 DOM 树。他们将 Firefox 进程做成了 HTTP 代理的形式,对外部应用提供服务。

而我们的 List Hunter 集群中的 Firefox 进程则是高度自治的爬虫,它们自己从 OpenResty 中不断地批量取任务去完成。而外部应用则是批量地向 OpenResty 导入任务来让集群运转。由于 List Hunter 集群并没怎么修改 Firefox 的源代码,这使得我们可以很容易地与官方最新版本保持同步,从而第一时享受到官方优化带来的众多好处。

同时 List Hunter 集群本身是通用目的的,它可以作为各种 Firefox 插件的"集群容器"。换言之,这是一种将 Firefox 插件"集群化"的完整的框架。

由于 Firefox 插件开发本身已经通过我发布到 CPAN 的 XUL::App 框架得到了极大的简化,所以响应新的需求的成本是非常低的。

=head1 使用 Firefox 的利与弊

=over

=item 优点

Firefox 是世界级的浏览器。作为最复杂功能最丰富的 Internet 客户端之一,我们将之作为爬虫可以享受到和最终用户一样的丰富功能,无论是 AJAX 还是视觉信息都不是问题。

Firefox 有基于 XUL 和 chrome JS 的灵活的插件机制,极易扩展。事实上,Firefox 主界面自身就是一个大插件。同时,Gecko 是基于 XPCOM 组件方式的,因此可以很容易地使用 C/C++/Java 等语言开发 XPCOM 组件,然后再用 JavaSscript 把它们粘合在一起。于是乎,JavaScript 成为了像 Perl 一样的胶水类语言。

运行于 Gecko 之上的插件 JavaScript 拥有最高权限,这种 JS 可以访问磁盘文件,可以访问系统环境变量,可以使用原生的 XmlHttpRequest 对象发出跨域 AJAX 请求。

Firefox 的性能随着新版本的发布总会有戏剧性的变化。Firefox 3.1 中的 Gecko 引擎的渲染速度就比 3.0 中的快了好几倍(根据 List Hunter 回归测试集的 benchmark 结果,前者为平均 60 ms,后者则长达 200+ ms)。(Firefox 3.1 中 TraceMonkey 的 JIT 支持倒并没有给 List Hunter 中的 JS 带来可测量的性能提升。)

纯 JS 写的 Firefox 插件可以在 Win32/Linux/Mac 多种操作系统上即装即用,所以方便和编辑及产品经理沟通行为细节,方便演示。如若计算过于复杂,亦可使用 C++ 语言改写插件中的计算密集的部分。

=item 缺点

Firefox 是高耦合的软件,这与 Google Chrome 及 Safari 浏览器的核心 Webkit 形成了鲜明对比。这意味着,我们比较难于对 Firefox 进行深层次的裁剪,无法轻易地免除一些比较大的功能部件,也很难将其中的某一个大部件剥出来单独使用(当然了,SpiderMonkey 是少数几个例外之一)。

=back

=head1 AUTHOR

章亦春 (agentzh) C<< <agentzh@yahoo.cn> >>

=head1 LICENSE

Copyright (c) 2007-2008, Yahoo! China EEEE Works, Alibaba Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

=over

=item *

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

=item *

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

=item *

Neither the name of the Yahoo! China EEEE Works, Alibaba Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

=back

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm



--
>: ~

2008年12月24日星期三

Re: [PerlChina] 答复: 各位圣诞快乐哦!

您太客气了  我水平有限 很多地方没能理解  但是收获不小  非常感谢

Date: Thu, 25 Dec 2008 15:22:01 +0800
From: agentzh@gmail.com
To: china-pm@pm.org
Subject: Re: [PerlChina] 答复: 各位圣诞快乐哦!

2008/12/25 agentzh <agentzh@gmail.com>
2008/12/25 wbi � <wbisearchina@hotmail.co.jp>
>
>  Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?

=head1 NAME

List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。


感谢你的提问。。。不自觉又一篇文档 + blog 贴子有了 ^_^

Thanks!
-agentzh


「ブリ�フケ�スからお引越し」�料25GBのファイル保存サ�ビス Hotmail ユ�ザ�なら、すぐに利用可能です!

Re: [PerlChina] 请问有什么便捷的方法载入zip包里的库?

2008/12/25 Luo Yong <luo.yong.name@gmail.com>
多谢,

这个方法大概是最好的方法了,不过感觉Java的那种用JAR文件封装类库的方法很方便,但是在perl上暂时没办法实现,不知道perl6里有没有类似的功能。


CPAN 上有一个叫做 pp 的工具可以把 Perl 5 类库封成 PAR 文件 ;)

基于 parrot 的 Perl 6 中可以在字节码级别进行联编,就更方便了 ;)

-agentzh

Re: [PerlChina] 答复: 各位圣诞快乐哦!

2008/12/25 agentzh <agentzh@gmail.com>
2008/12/25 wbi � <wbisearchina@hotmail.co.jp>
>
>  Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?

=head1 NAME

List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。


感谢你的提问。。。不自觉又一篇文档 + blog 贴子有了 ^_^

Thanks!
-agentzh

Re: [PerlChina] 答复: 各位圣诞快乐哦!

2008/12/25 wbi � <wbisearchina@hotmail.co.jp>
>
>  Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?

=head1 NAME

List Hunter cluster - 这个是我们自己基于 Mozilla Firefox 3.1 做的深抓爬虫集群,名为 List Hunter 集群。目前是我们公司生活搜索引擎的一部分。

=head1 背景

在我们的生活搜索项目中,需要对网页进行深层次的识别和抽取。基于文本内容的分类我们目前采用的是美国雅虎基于最大熵的 DCP 系统。而对于网页结构方面的分类(即这个网页是列表页呢,还是详情页?),以及主体链接列表、主体区域抽取,则一直缺乏比较好的解决方案。我的同事尝试过通过纯粹的结构化的方法(如海维算法)进行识别,准确率只有 60%,而基于 SVM 这样的机器学习的方法,对网页类型比较敏感,如目标网页与训练集相差较多,则准确率迅速下降。

于是我尝试把网页显示时的视觉信息结合到海维算法以及块合并算法中。于是准确率和召回率分别达到了 90% 和 80%。这里的视觉信息主要包括一个网页区域的大小、形状、和在整个页面中的位置。更多的信息还包括字体、颜色等等。这样,便诞生了 List Hunter 插件。于是如何将 Firefox 插件做成一个大规模的集群用于生产,便成为了重要问题。

在下面这篇 blog 文章中我介绍了更多背景方面的细节以及 List Hunter 插件本身的情况:

    http://blog.agentzh.org/#post-97

=head1 集群的结构

该集群由四大部分组成:纯 Firefox 集群,Apache + mod_proxy + mod_disk_cache 集群,curl 预取器集群,和 OpenResty 集群。一共有十几台生产机"全职"或者"兼职"地参与了这个集群。下面逐一介绍一下哈:

=over

=item 纯 Firefox 集群

纯 Firefox 集群目前由 8 台 4 核的 redhat5 生产机组成。每台生产机运行 3 个 Firefox 3.1 进程实例。因为那 8 台机器同时服务于淘宝 VIP 搜索的商口图片显示接口(大约 600 万日 PV),所以我们没敢在这些机器上运行比较多的 Firefox 进程。

需要指出的是,Firefox 默认是"进程复用"的运行方式。即启动多次 firefox-bin 可执行程序,其实得到的还是单个 Firefox 进程。这种进程复用方式无法充分利用生产机的多核 CPU。因为在任意给定时刻,一个进程只能跑在一个核上,哪怕它是多线程的。为了让 Firefox 以多进程方式运行,需要:

=over

=item 1.

在调用 firefox-bin 程序时指定 -no-remote 命令行选项,或者设置环境变量 MOZ_NO_REMOTE=1

=item 2.

以不同的 profile 运行不同的 firefox-bin 进程(利用 -P 命令行选项)。

=back

我们平常看到的 Firefox 的主窗口并不启动,而以 chrome 方式单独运行 List Hunter 插件的界面,例如:

    firefox -chrome chrome://listhunter/content/crawler.xul -P crawler2 -no-remote

以 chrome 方式运行的插件与 XULRunner 方式运行的 XUL 应用是很类似的。

由于 Firefox 3.1 还没有正式发布,我直接 checkout 官方 Mercurial 源码仓库内的最新版本,自己在我们的 redhat 生产机上编译的。我们目前几乎没有修改官方的 C++ 源代码,为了方便和官方版本保持同步。我们目前使用的是下面的 firefox 编译选项:

  # My .mozconfig
  mk_add_options MOZ_MAKE_FLAGS="-j2"
  mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
  ac_add_options --enable-crypto --enable-feeds --disable-profilesharing --enable-rdf --enable-zipwriter --disable-tests --disable-gnomeui --disable-cookies --disable-canvas --disable-gnomeui --disable-inspector-apis --disable-mailnews --disable-mathml --disable-official-branding --enable-plaintext-editor-only --disable-postscript --disable-printing --disable-profilelocking --disable-safe-browsing --disable-startup-notification --disable-svg --disable-svg-foreignobject --disable-updater --disable-javaxpcom --disable-plugins --disable-crashreporter --disable-tests --disable-debug --enable-application=browser --build=i686-linux --disable-jsd --disable-ldap --enable-strip --disable-accessibility --disable-ogg --disable-dbus --disable-freetype2 --disable-optimize

这里能禁用的功能我们都禁用了,这里的 feeds, rdf, crypto 这三个都不能 disable,否则源码编译不通过,会报一些 .h 头文件找不到,呵呵。--disable-ogg 实际上也不起作用,但网上的材料看曾经有效过,呵呵。

事实上,目前我们还是给官方的源码打了一个 C++ 补丁,用于将 Error Console 中的 Errors 重定向到 stderr,这样方便我们在集群环境下通过 Firefox 进程的 log 文件捕捉和诊断一些异常。目前的补丁是下面这个样子:

    http://agentzh.org/misc/191src.patch.txt

值得一提的是,Firefox 进程本身是"无头"的,即它运行在 Xvfb 这个 X server 之上,只在内存里执行渲染,而不需要任何显示硬件的存在。这些 Firefox 进程本身是挂在我们自己的一个 Perl 写的进程监控脚本之下。该脚本来自我们的 Proc::Harness 模块:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/Proc-Harness/

Proc::Harness 会像 lighttpd 的 Fastcgi server 一样,维护一组指定数目的进程(通过 CPAN 上的 Proc::Simple 模块)。当子进程挂掉后立即重启,或者当子进程的 stderr/stdout 输出不再变化一段时限之后也杀之重启。Proc::Harness 脚本自身则是挂在了 deamontools 之下。

这些 Firefox 进程受安装在其中的 List Hunter 插件的完全控制。它们都是高度自治的 robot。它们内部有一个处理循环,一批一批地从 OpenResty 的 web service 接口取到 URL 任务,然后一个一个地在 Firefox 的 browser 组件里加载和分析,最后把分析到的结果一批一批地通过 OpenResty 提交之。

=item curl 预取爬虫集群与 Apache mod_proxy 集群

该集群目前布署了 6 台双核的 redhat4 生产机。每台机器都安装了两个集群组件,一是预取器,一是 Apache mod_proxy. 预取器的作用是通过 curl (准确地说是 WWW::Curl 模块)将网页的 HTML 和 CSS 通过 mod_proxy 预取一遍,这样这些请求的结果就可以在 mod_proxy 中通过 mod_disk_cache 缓存住。于是当纯 Firefox 集群再通过 mod_proxy 去抓这些 URL 时,mod_proxy 就可以直接把缓存后的结果直接返回给 Firefox 了。

预取器和 Firefox 进程是同时工作的,但对于一个 URL 任务而言,只有通过预取器预取过之后,Firefox 进程才会进行处理。所以实际构成了一个两道工序的流水线。这种调度是由 OpenResty 集群来完成的。

预取器目前是以一个叫为 WWW::Prefetcher 的 Perl 模块的形式来实现的:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/WWW-Prefetcher/

虽然 mod_cache 提供了许多选项,但其缓存行为还是比较遵守 RFC 的 cache 要求的。因此我对 mod_cache 模块进行了许多修改,使之可以无条件地缓存住请求过的所有网页,而不论其 URL 是否有 querystring,也不论其 response header 中的要求是什么。我们对最新的 httpd 2.2.11 的补丁如下:

    http://agentzh.org/misc/httpd-2.2.11.patch.txt

特别地,mod_disk_cache 指向的不是磁盘目录,而是 RAM 中开辟的 tmpfs 分区。由于我们这 6 台机器都是很旧的 IDE 硬盘,因此直接用磁盘作 cache 存储时,高并发条件下,每台机器的 load 都在 20 以上,根本无法忍受。后来换为 tmpfs 结果 htcacheclean 工具之后,机器负载就降到 0.1 以下了。

=item OpenResty集群

由于 OpenResty 的通用性,我们直接复用了同时服务于 yahoo.cn 和口碑网的那个生产集群,(3 台 FastCGI 前端机和1 台 PL/Proxy 机器),所以我就没有布署新的机器。在服务于 Firefox 集群的 OpenResty 接口中通过 View API 暴露了若干的 PostgreSQL 函数,以完成整个 List Hunter 集群的任务调度和结果汇总。目前的实现中,我们通过 Pg 的 sequence 摸拟了一种循环任务队列,并通过计数器完成流水线中两道工序之间的相对同步。

相关的 Pg 函数、sequence、以及索引的定义在这里:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-db.sql

相关的 OpenResty 对象的定义则在这里:

    http://svn.openfoundry.org/xulapp/trunk/demo/ListHunter/misc/init-resty.pl

=back

=head1 集群的性能

集群目前每小时的产出稳定在 10 万网页以上,一天的产出在 240 万以上。Firefox 机器的负载在 3 左右,Proxy 的负载在 0.1 以下。

JS 基准测试显示 Firefox 3.1 加载一个页面的平均延时是 200 ~ 300 ms,机房间的网络延时在 10 ~ 20 ms(因为网页已被 mod_cache 缓存住,故无到外网的网络开销), List Hunter 插件的 DOM 分析代码的用时在 200 ~ 300 ms。其他 OpenResty 开销再计入,大约 1 sec 处理一个页面。

=head1 已知瓶颈和缺陷

当 OpenResty 中的 URL 任务表的行数超过 100 ~ 200 万时,调度查询容易超过 PL/Proxy 的 10 秒限制。因此,我们目前采取"流式"的任务导入和导出方式。通过 cronjob 定期地向库中导入任务,并同时把完成了的任务及时移出。

Apache 的 mod_proxy 在高并发条件下不够稳定,而且限于 Apache 自身的体系结构,无法实现 proxy pipelining. 因此计划在未来集群规模进一步扩大时,改用 Squid. 当然了,Squid 很可能也需要进行修改才能满足我们这里的强制缓存一段指定时间的需求。

同时,受限于 Apache mod_cache 后端的非分布式,代理服务器的调度是在 Firefox 进程和 curl 预取进程中完成的,导致前端代码比较复杂,还带来了代理服务器列表的定时同步问题。因此,未来可以考虑为 Apache mod_cache 或者 Squid 添加 memcached 缓存后端的支持。这样代理前端的多台服务器可以实现对集群内其他部件的"透明化"。

=head1 TODO

=over

=item 1.

换用 Squid + memcached 作为缓存用正向代理

=item 2.

通过 XULRunner 而非 firefox -chrome 方式运行 List Hunter 插件。(需要为我的 XUL::App 框架添加 XULRunner 支持)

=back

=head1 与相似产品的异同

美国雅虎通过大量修改 Firefox 2 的 C++ 源代码,开发了叫为 HLFS 的爬虫集群,用于爬取 AJAX 网站的内容以及得到带有视觉信息的 DOM 树。他们将 Firefox 进程做成了 HTTP 代理的形式,对外部应用提供服务。

而我们的 List Hunter 集群中的 Firefox 进程则是高度自治的爬虫,它们自己从 OpenResty 中不断地批量取任务去完成。而外部应用则是批量地向 OpenResty 导入任务来让集群运转。由于 List Hunter 集群并没怎么修改 Firefox 的源代码,这使得我们可以很容易地与官方最新版本保持同步,从而第一时享受到官方优化带来的众多好处。

同时 List Hunter 集群本身是通用目的的,它可以作为各种 Firefox 插件的"集群容器"。换言之,这是一种将 Firefox 插件"集群化"的完整的框架。

由于 Firefox 插件开发本身已经通过我发布到 CPAN 的 XUL::App 框架得到了极大的简化,所以响应新的需求的成本是非常低的。

=head1 使用 Firefox 的利与弊

=over

=item 优点

Firefox 是世界级的浏览器。作为最复杂功能最丰富的 Internet 客户端之一,我们将之作为爬虫可以享受到和最终用户一样的丰富功能,无论是 AJAX 还是视觉信息都不是问题。

Firefox 有基于 XUL 和 chrome JS 的灵活的插件机制,极易扩展。事实上,Firefox 主界面自身就是一个大插件。同时,Gecko 是基于 XPCOM 组件方式的,因此可以很容易地使用 C/C++/Java 等语言开发 XPCOM 组件,然后再用 JavaSscript 把它们粘合在一起。于是乎,JavaScript 成为了像 Perl 一样的胶水类语言。

运行于 Gecko 之上的插件 JavaScript 拥有最高权限,这种 JS 可以访问磁盘文件,可以访问系统环境变量,可以使用原生的 XmlHttpRequest 对象发出跨域 AJAX 请求。

Firefox 的性能随着新版本的发布总会有戏剧性的变化。Firefox 3.1 中的 Gecko 引擎的渲染速度就比 3.0 中的快了好几倍(根据 List Hunter 回归测试集的 benchmark 结果,前者为平均 60 ms,后者则长达 200+ ms)。(Firefox 3.1 中 TraceMonkey 的 JIT 支持倒并没有给 List Hunter 中的 JS 带来可测量的性能提升。)

纯 JS 写的 Firefox 插件可以在 Win32/Linux/Mac 多种操作系统上即装即用,所以方便和编辑及产品经理沟通行为细节,方便演示。如若计算过于复杂,亦可使用 C++ 语言改写插件中的计算密集的部分。

=item 缺点

Firefox 是高耦合的软件,这与 Google Chrome 及 Safari 浏览器的核心 Webkit 形成了鲜明对比。这意味着,我们比较难于对 Firefox 进行深层次的裁剪,无法轻易地免除一些比较大的功能部件,也很难将其中的某一个大部件剥出来单独使用(当然了,SpiderMonkey 是少数几个例外之一)。

=back

=head1 AUTHOR

章亦春 (agentzh) C<< <agentzh@yahoo.cn> >>

=head1 LICENSE

Copyright (c) 2007-2008, Yahoo! China EEEE Works, Alibaba Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

=over

=item *

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

=item *

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

=item *

Neither the name of the Yahoo! China EEEE Works, Alibaba Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

=back

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Re: [PerlChina] 请问有什么便捷的方法载入zip包里的库?

多谢,

这个方法大概是最好的方法了,不过感觉Java的那种用JAR文件封装类库的方法很方便,但是在perl上暂时没办法实现,不知道perl6里有没有类似的功能。

2008/12/25 agentzh <agentzh@gmail.com>:
> 2008/12/25 Luo Yong <luo.yong.name@gmail.com>
>>
>> 大家好,
>>
>>
>> 我想在我的个人主页空间里加入一些CGI,一些pm是自己写的,服务器的FTP不是很好用,所以想把这些pm打成一个zip包上传上去,但是不知道如何配置才能在脚本里引用,谁有好的方法麻烦告知一下。
>
> use lib '/path/to/my/pm/directory';
> use MyModule;
>
> or
>
> BEGIN { unshift @INC, '/path/to/my/pm/direcotry' }
> use MyModule;
>
> or
>
> perl -I/path/to/my/pm/direcotry myscript.pl
>
> Good luck!
> -agentzh
>
>
> _______________________________________________
> China-pm mailing list
> China-pm@pm.org
> http://mail.pm.org/mailman/listinfo/china-pm
>
_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm

Re: [PerlChina] 答复: 各位圣诞快乐哦!

同问...这里的Firefox指的是浏览器么?

2008/12/25 wbi � <wbisearchina@hotmail.co.jp>
 Firefox 3.1 集群 是怎么个原理啊 能给介绍介绍不?


Date: Thu, 25 Dec 2008 11:45:09 +0800
From: agentzh@gmail.com
To: china-pm@pm.org
Subject: Re: [PerlChina] 答复: 各位圣诞快乐哦!


2008/12/25 Qiao Wang <qiao.wang@magnumsemi.com>
圣诞快乐。 柔弱的问问大家,都用perl来干嘛呢。我只是用perl来控制我们的编译系统,生成C程序,和调试时分析A/V的码流。

我这些日子在用 Perl 做 Firefox 插件,以及配合 bash 作 Firefox 3.1 集群的"胶水",而调度整个 Firefox 集群的 OpenResty 这个 web service 平台也用 Perl 写的,哈哈!当然,这只是"这些日子"使用 Perl 的地方,其他日子就数不胜数了,呵呵。

Merry Christmas!
-agentzh

P.S. 用 Perl 生成 C 代码也是我最喜欢的,哈哈,无论是从 AST 生成 C 还是用 TT2 模板生成 C 抑或是 Verilog HDL。。。



豪�プレゼン トが抽�で当たる。『六本木ラグジュアリ�ナイト』 この冬限定のプレゼント。今すぐ�募を!

_______________________________________________
China-pm mailing list
China-pm@pm.org
http://mail.pm.org/mailman/listinfo/china-pm



--
lobatt