第8课:缓存

当产品用户量越来越大的时候,服务器压力会不断上升,这个时候,优化势在必行,而在优化方法中,缓存是用的最多的

缓存也分几个层次,有在前端缓存的,中间层缓存的,还有服务端缓存的
前端主要是对静态页面,图片,JS CSS等进行缓存
服务端主要是用一些NOSQL数据库来进行缓存,现在主流的是redis与mongodb
NGINX服务器也有proxy cache模块,缓存效率也挺高,如果条件不允许,用这个做缓存也是不错的选择
nginx设置缓存JS CSS

#图片缓存时间设置  
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$  
{  
    expires 8d;  
}  
#JS和CSS缓存时间设置  
location ~ .*.(js|css)?$  
{  
    expires 2h;  
}  

有了缓存自然就有去除缓存的需求,一般都会采选在文件名后面加随机数来获取最新资源,而proxy cache,varnish清除缓存需要通过专门的操作来删除掉缓存文件
比如godeye.js要想获取最新的可以用godeye.js?a=1234567799

另介绍一款HTTP加速器
Varnish是一款高性能、开源的反向代理服务器和缓存服务器
条件优越的话可以用这个来做缓存,比简单用nginx缓存模块来做要好很多

NoSQL缓存
推荐redis memcache couchbase mongodb
缓存模式
1.1 先查缓存内容存在不存在,如果不存在,查询数据库,如果有内容,写入缓存设置过期时间,并把结果返回
1.2 用户在写操作的时候直接写入一份到缓存,持久化保存,读取时候直接读取缓存
1.3 如果是有过期时间的缓存,数据有更新,可以直接把对应缓存删除掉
1.4 如果是持久化缓存,数据有更新,可以直接修改缓存
都有对应的PHP的api或者扩展,这里不再累述

页面静态缓存
ob_start();
ob_end_flush();
ob_get_contents();
比如你用得到服务器和客户端的设置信息,但是这个信息会因为客户端的不同而不同,如果想要保存phpinfo()函数的输出怎么办呢?在没有缓冲区控制之前,可以说一点办法也没有,但是有了缓冲区的控制,我们可以轻松的解决:
<?php  
    ob_start(); //打开缓冲区  
    phpinfo(); //使用phpinfo函数  
    $info=ob_get_contents(); //得到缓冲区的内容并且赋值给$info  
    $file=fopen('godeye.txt','w'); //打开文件godeye.txt  
    fwrite($file,$info); //写入信息到godeye.txt  
    fclose($file); //关闭文件godeye.txt
?> 
用以上的方法,就可以把不同用户的phpinfo信息保存下来,这在以前恐怕没有办法办到!其实上面就是将一些"过程"转化为"函数"的方法

缓冲区的作用总结
1.用于header()之前
<?php
ob_start(); //打开缓冲区
echo /"Godeye/"; //输出
header("location:godeye.php"); //把浏览器重定向到godeye.php
ob_end_flush();//输出全部内容到浏览器
?>

2.phpinfo()函数可获取客户端和服务器端的信息,但要保存客户端信息用缓冲区的方法是最好的选择
<?php
ob_start(); //打开缓冲区
phpinfo(); //使用phpinfo函数
$info=ob_get_contents(); //得到缓冲区的内容并且赋值给$info
$file=fopen(/'info.txt/',/'w/'); //打开文件info.txt
fwrite($file,$info); //写入信息到info.txt
fclose($file); //关闭文件info.txt
?>

3.静态页面技术
<?php
ob_start();//打开缓冲区
//php页面的全部输出
$content = ob_get_contents();//取得php页面输出的全部内容
$fp = fopen("godeye.html", "w"); //创建一个文件,并打开,准备写入
fwrite($fp, $content); //把php页面的内容全部写入godeye.html,然后……
fclose($fp);
?>

4.输出代码
function runCode($code) {
	if($code) {
	    ob_start();
	    eval($code);
	    $contents = ob_get_contents();
	    ob_end_clean();
	}else {
	    echo "错误!没有输出";
	    exit();
	}
	return $contents;
}