« 如何捕捉CGI程序exception | Main | 发布lilina 预缓存补丁(lilina cache patch) »

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明。
本文网址:http://www.hzqbbc.com/blog/arch/2005/05/aelilinaechtml.html
 

May 11, 2005

为lilina增加文本预缓存支持(html cache)

Lilina是一个不需要使用数据库的RSS新闻聚合器,由PHP编写而成,而且不需要数据库支持,纯文本操作,非常方便。

但lilina的缺点也是很明显的,最严重的问题是性能/速度(performance!),虽然lilina已内置了cache功能,但如果订阅的新闻源一多,由于遍历的文件也随之增加,因此速度会越来越慢。

我用lilina做首页,很多朋友都反映速度很慢。于是琢磨着给其提速,好几年没写过php了,估计快忘光了。于是到www.php.net去找找资料。

提速原理:Cache

大部分的web提速都是基于缓冲(cache)的原理,将输出的内容保存到一个静态文件里,在一定周期(Life time)内将结果从静态文件(cache file)里直接提取甚至直接输出这个静态文件。因此避免了大量的数据库或速度缓慢的操作,可大幅度提高性能。

lilina的缺陷很明显,输出是由index.php完成。不可避免的需要大量耗时的操作。能否将输出的结果Cache起来呢?默认lilina 的cache data life time 是60*60秒(1小时),那么在1小时内,每次访问都只是访问cache而已,如果将输出结果保存成html文件,无疑能极大的提高速度。

基本构思

如何捕获lilina的输出呢?这个是关键问题。chedong的做法是使用wget来“获取”输出,保存到index.html里,这样最大的好处是实现简便,不需要任何额外的技术。只要系统安装了wget,在crontab里加一个定期更新index.html的指令即可。有关chedong的wget实现请参阅Lilina的简单预缓存加速

但wget一法有一些小缺陷,对于虚拟主机用户没有crontab的权限,因此这个方法不太可行。而通过修改lilina的输出头,由浏览器代为Cache也是一个可行的方法。

但我有个癖好,喜欢pure solution,希望不借助任何其他工具,在lilina里实现快照(Cache)提速。基本原理很简单:,利用php的Output Control技术,捕获php的输出,将输出写入Cache文件index.html里。如果在一定周期内Cache不过期,则不需要重建。

具体实现

真正需要涉及的Output Control函数是ob_start()和ob_end_flush(),前者标记了output buffering 开始,而后者则刷新buffer,将结果输出。

以下是基本代码结构:


<?PHP
ob_start("callback"); // begin output buffer

/* some varible defination goes here */
$index_file = "/path/to/index.html";
$mt = mtime();
$rebuild = 0;

if(time() - $mt > 3600) { // cache file expire?
         $rebuild = 1; // rebuild it
}else {
         return 0; // ignore RSS process
}

/* cache index hack functions */
// get cache file modify time
function mtime() {
         global $index_file;
         $fd = fopen($index_file, "r");
         $fstat = fstat($fd);
         fclose($fd);
         return $fstat['mtime'];
}

// callback func for ob_start()
function callback($str) {
         global $rebuild, $index_file, $mt;
         if($rebuild) {
                  $fd = fopen($index_file, "w");
                  fputs($fd, $str, strlen($str));
                  fclose($fd);
                  return "Index rebuild done";
          }else {
                  return "Using cache index";
          }
}

/* begin the main RSS processing..*/
......
?>
some html..

<?PHP
ob_end_flush();
?>

代码的实质功能无非是:检查cache文件是否过期,如过期则设置rebuild标记,如没有则终止程序。通过ob_start()设置了一个叫callback的回调函数,从而捕获了整个程序的输出,并保存到本地的index.html里。

...to be continue..

Posted by hzqbbc at May 11, 2005 11:41 AM

Comments

lilina在不转换为html时奇慢无比,都没法使用了。这个技术成熟吗?

Posted by: 于铁锋 at May 13, 2005 10:44 AM

忘了跟您说了,暂时用了您lilina下的样式表,来征求您的同意。

Posted by: yutiefeng at May 13, 2005 10:47 AM

这个方法目前证明没有什么问题,至于速度就主要是html的速度了,稳定可靠。暂时没发现问题。

过两天整理好代码,做成一个lilina的patch,包括一个简单的文档。提供下载

Posted by: hzqbbc at May 13, 2005 09:27 PM

较为关注lilina 0.70
但自己本身非玩程序 稍微懂点ASP
对于Lunix PHP基本不了解
希望能得到hzqbbc您的帮助

QQ:356964063

Posted by: 若寒 at August 2, 2005 11:32 PM

:)

Posted by: 若寒 at August 2, 2005 11:34 PM

希望能尽快得到你回复 谢谢

Posted by: 若寒 at August 2, 2005 11:34 PM

Post a comment




Remember Me?

(you may use HTML tags for style)