WEB缓存原理

4 篇文章 0 订阅
2 篇文章 0 订阅
先简单说下什么是缓存:缓存简单说来就是把一个 代码 执行过程产生的输出保存起来,可以存放在硬盘,内存,或者其他服务器上,

 

缓存可以是任意格式的文件,内容也可以是完整的HTML,HTML片段XML,几个字符,一串字符串,比较常见的就是缓存文件例如smarty,smarttemplate模版的缓存,这个就是保存的html片断,而开源的discuz,phpwind等论坛程序,就是保存的字符串,这个字符串的特点就是一段完整的PHP代码,直接用include包含这个缓存文件就可以得到相关数组。还有些格式比如说小巧的sqlite,将PHP序列化为字符串保存在文件里,用的时候再反序列化等手段,其过程都是类似的。

 

现在说更新缓存:通常的做法是在取缓存的时候先根据相关条件(如模版改动,缓存过期数据库变动等)判断缓存文件是否需要更新,如需更新则直接进行缓存更新,所以,一般有这样的代码片段:(以伪代码示例)
if(需要更新缓存==true){
这里就是缓存文件产生过程
}else{

取缓存文件的数据

}

 

这样的方式可以称为同步更新缓存,同步更新有几个缺点,一是并发大了的情况,在更新文件的同时,另一个进程正在包含这个文件,有可能造成文件读写错误,二是如果更新过程过于慢长,用户端得到的一片空白,严重降低了用户体验。可以采取异步更新的机制来完善以上2个缺陷:当服务端检查到缓存需要更新,但并不立即更新,输出javascrīpt对客户端进行提示(需要更新缓存,请等待)或者压根就不提示用户,而采用过去缓存,并使用ajax或者包含框架的方式再次请求服务器,这次服务器才更新缓存,下一次请求就稍做检查就用上新缓存了,这样很容易的解决了以上问题,用户体验也不错,感觉不到空白的延迟时间段。


举一个很简单的例子来说明异步更新缓存的过程:用户查询名字为包含xxx的数据:很明显这个查询语句是select name from table where name like '%xxx%'是全表搜索,name上的索引无效,我们可以把这个查询出来的数据做成xml,或者直接序列化结果保存在文件,文件名就为xxx,如果是搜索yyy的话,我们建立的文件名可以是yyy,遇见下一次查询用户名为xxx的时候,我们就可以直接取这个xxx缓存文件,从而饶开了查询数据库,这个是很好理解的。

如果某时间insert了name包含xxx的数据,再新的查询中,我们需要进行缓存更新,现在我们则采用异步更新缓存的思路进行:直接给客户端返回js,提示需要等待更新,当新的xxx文件更新之后,服务端再输出js通知更新完毕,然后直接进行结果查看页,这个过程强调了用户体验,用户根本看不到空白的等待返回结果的信息,感觉到整个过程更加流畅。

实例代码:

<?php
        define("_CachePath_","./cache/");
        define("_CacheEnable_","1");
        define("_ReCacheTime_","43200");
        include('cache.php');
        $cache=new cache();
        if ($cache->check()) {
        $template=$cache->read();
                }else {
                ob_start();
                ob_implicit_flush(0);
?>
                                  页面内容。。。。
<?php
        $template = ob_get_contents();
        $cache->write($template);
        }
?>

 

<?

class cache {

var $cachefile;
var $cachefilevar;

function cache() {
        //生成当前页的Cache组文件名 $this->cachefilevar 及文件名 $this->cachefile
        //动态页的参数不同对应的Cache文件也不同,但是每一个动态页的所有Cache文件都有相同的文件名,只是扩展名不同
        $s=array(".","/");$r=array("_","");
        $this->cachefilevar=str_replace($s,$r,$_SERVER["SCRIPT_NAME"])."_".$_GET[_ActionVar_];
        $this->cachefile=$this->cachefilevar.".".md5($_SERVER["REQUEST_URI"]);
}

//删除当前页/模块的缓存
function delete() {
        //删除当前页的缓存
        $d = dir(_CachePath_);
        $strlen=strlen($this->cachefilevar);
        //返回当前页的所有Cache文件组
        while (false !== ($entry = $d->read())) {
                    if (substr($entry,0,$strlen)==$this->cachefilevar) {
                            if (!unlink(_CachePath_."/".$entry)) {echo "Cache目录无法写入";exit;}
                    }
            }
}

//判断是否已Cache过,以及是否需要Cache
function check() {
        //如果设置了缓存更新间隔时间 _ReCacheTime_
        if (_ReCacheTime_+0>0)        {
                //返回当前页Cache的最后更新时间
                <a href="mailto:$var=@file(_CachePath_." ".$this-%3ecachefilevar);$var="$var[0"" style="text-decoration: none; color: rgb(91, 112, 48);">$var=@file(_CachePath_."/".$this->cachefilevar);$var=$var[0];
                //如果更新时间超出更新间隔时间则删除Cache文件
                if (time()-$var>_ReCacheTime_) {
                        $this->delete();$ischage=true;
                }
        }
        //返回当前页的Cache
        $file=_CachePath_."/".$this->cachefile;
        //判断当前页Cache是否存在 且 Cache功能是否开启
        return (file_exists($file) and _CacheEnable_ and !$ischange);
}

//读取Cache
function read() {
        //返回当前页的Cache
        $file=_CachePath_."/".$this->cachefile;
        //读取Cache文件的内容
        if (_CacheEnable_) return readfile($file);
        else return false;
}

//生成Cache
function write($output) {
        //返回当前页的Cache
        $file=_CachePath_."/".$this->cachefile;
        //如果Cache功能开启
        if (_CacheEnable_) {
                //把输出的内容写入Cache文件
                $fp=@fopen($file,'w');
                if (!@fputs($fp,$output)) {echo "模板Cache写入失败";exit;}
                @fclose($fp);
                //如果设置了缓存更新间隔时间 _ReCacheTime_
                if (_ReCacheTime_+0>0) {
                        //更新当前页Cache的最后更新时间
                        $file=_CachePath_."/".$this->cachefilevar;
                        $fp=@fopen($file,'w');
                        if (!@fwrite($fp,time())) {echo "Cache目录无法写入";exit;}
                        @fclose($fp);
                }
        }
}

}
?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值