zoukankan      html  css  js  c++  java
  • php缓存与加速分析与汇总

    作者:phpben

    来源:http://www.phpben.com/?post=80

    这篇博文笔者构思了很久,当然也写了很久,发现想到和写出来完全两码事,写下来会更深刻些弄清很多模糊概念。看张图

    环境:win7 32 + apache2.2 + php5.28 +  5.1.49-community + chrome 22.0.1
    一、    浏览器端缓存
    要利用浏览器缓存则要先了解http协议内容,这里主要利用http协议头部header的一些头域名,主要“Expires”,“Etag”,“Last-Modified”;
    先看张原理图:


    当然还有其他http头域上图没说明,要详细点了解http协议和不同浏览器4个浏览器操作的解释可以移步:
    http://www.phpben.com/?post=77
    还有如何通过浏览器监听http请求(笔者喜欢用chrome):
    http://www.phpben.com/?post=76
    ps:下面给出的http请求头部监听结果都是在chrome浏览器下的结果

    1、先来了解几个问题
    (1)在没任何缓存情况下。浏览器请求一个页面发送http请求不止一次,要根据页面中uri资源个数而定。
    在http协议中,浏览器第一次处理服务器返回web内容的时候,也就是浏览器还没任何缓存的时候,向服务器发送http请求数是多个,也就是说浏览器不是一次处理完一个页面中所有uri资源。
    百度首页部分http请求图:
    说明: C:UsersBskyDesktop11.jpg
    你会发现status(状态行)都是200,size内容都是笫一次加载。
    注意:测试时要确保没缓存,仅仅在浏览器清除是不彻底的,要到相应缓存库中删除所有,如笔者路径的:C:UsersbenwinAppDataLocalGoogleChromeUser DataDefaultCache ,否则你会看到如下(这是第二次刷新,浏览器已有缓存)
    说明: C:UsersBskyDesktop2.jpg
    这也是一些前端强调写css的时候把一些图标,按钮图片合成一张用background-position定位坐标,这样加载时只请求一次则把所有图标加载完。
    (2)apache对处理静态文件和动态文件返回头部信息有所不同。
    Apache对于浏览器请求html、css、js、图片等文件时返回头部信息时会自动加上etag(apache默认打开),last-modified头域,而动态文件如php后缀文件则不会,除非php文件代码中加入header("Expires: …")、header("Last-modified:…")、header("Etag…")。
    代码:

    1. <?php
    2. echo '<script src="test.js" type="text/javascript"></script>
    3. <link rel="Stylesheet" type="text/css" href="test.css" />
    4. <img src="test.jpg" />';
    5.  ?>

    加载效果和监听结果图:
    说明: C:UsersBenwinDesktopQQ截图20121107120709.jpg
    (3)浏览器利用expires头域和last-modified或etag的一个不同点。对于expires是先检查是否过期决定是否发请求;后两者是会发http请求给服务器,服务器判断是重新解析返回结果还是直接不用重新解析只返回304 Not Modified告诉浏览器请求内容没改变可以用原来的缓存。
    Expires:浏览器在服务器首次返回http头中若有expires头域且有效则缓存内容,第二次发请求前会先根据expires是否过期来决定是否发请求,没过期则不会发请求,而是从浏览器缓存中拿数据,如下图没过期的http监听效果图:说明: C:UsersBenwinDesktopQQ截图20121104200946.jpg
    上图status 200变白,和size显示from cache。过期则重新发http请求
    last-modifie:第一次请求服务器返回last-modified,浏览器第二次发请求前向服务器发If-Modified-Since(值是last-modified返回的值),服务器根据If-Modified-Since来判断文件是否修改来做不同反应,如果If-Modified-Since相同则返回 304 Not Modified,否则服务器发新的last-modified回去。浏览器第i次对于last-modified的处理和第二次相同。
    说明: C:UsersBenwinDesktop111.jpg
    Etag:浏览器对etag处理和对last-modified处理一样,只不多(last-modified,If-Modified-Since)配对,(etag,If-None-Match)配对。

    2、常见的缓存方法。
    (1)使用http Expires头域的时间缓存(有个有趣的情况)
    如下面告诉浏览器一小时过期代码:

    1. header('Expires:'.date('D, d M Y H:i:s GMT', time()+3600));

    适用范围:静态页面html如一些新闻网内容页
    笔者发现个有趣的事情
    代码1:

    1. header('Expires:'.date('D, d M Y H:i:s GMT', time()+60));
    2. session_start();
    3. $_SESSION['url']='www.phpben.com';

    http监听结果1:

    1. HTTP/1.1 200 OK
    2. Expires: Thu, 19 Nov 1981 08:52:00 GMT
    3. Content-Type: text/html
    4. ……

    代码2:

    1. session_start();
    2. header('Expires:'.date('D, d M Y H:i:s GMT', time()+60));
    3. $_SESSION['url']='www.phpben.com';

    http监听结果2:

    1. HTTP/1.1 200 OK
    2. Expires: Mon, 29 Oct 2012 13:49:19 GMT
    3. Content-Type: text/html
    4. ……

    笔者结论
    两个Expires结果因为session_start();的顺序不同结果不同。
    header('Expires:'.date('D, d M Y H:i:s GMT', time()+60));当后面有session_start();的时候,Expires会被改写成Expires:Thu, 19 Nov 1981 08:52:00 GMT,也就是Expires会被重写,也可以说是优先级别高,所以要在有session情况使用Expires所以要注意顺序问题,这里也说明expires方法在某种程度上不是很适合于动态页面-----话说笔者在这里吃了不少苦头
    (2)使用http last-modified和if-modified-since 头域的时间缓存
    实现代码:

    1. if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (time()-strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < 10))
    2. {
    3.     header("HTTP/1.1 304 Not Modified");
    4.     exit;
    5. }else
    6. {
    7.  //网上很多代码都没考虑齐全,都是下面两个版本之一而已
    8.  if (date_default_timezone_get()=='UTC')
    9.  {
    10.    header("Last-Modified:" . date('D, d M Y H:i:s GMT', time()));
    11.  }else //这是针对时区设为PRC、Asia/ShangHai等中国时区
    12.  {
    13.    header("Last-Modified:" . date('r', time()));
    14.  }
    15. }

    为什么要考虑两种情况(话说笔者以为是php一个bug后来检测了不是)。
    -------------
    环境:apche2.2+php5.2.8  和apache2.2+php5.3.3 和apache2.2+php5.4.7
    测试(1)
    代码:

    1. $a= date('D, d M Y H:i:s GMT', time());
    2. echo $a,'<br/>';
    3. echo date('D, d M Y H:i:s GMT', strtotime($a));

    说明: C:UsersBenwinDesktopphp缓存与加速222.jpg
    怎么多8小时了呢?
    utc时间=gmt时间
    utc时间+8小时=prc时间=北京时间(是不是忘记了?)
    而的结果也是类似多8小时
    所以如果你服务器time.zone设置utc没问题,但如果不是,则像以下代码是不起作用的

    1. if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (time()-strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < 10))
    2. {
    3.     header("HTTP/1.1 304 Not Modified");
    4.     exit;
    5. }
    6. header("Last-Modified:" . date('D, d M Y H:i:s GMT', time()));

    因为time()-strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])已经是负数
    根本原因:strtotime()函数转化成时检测到“GMT”然后在time.zone=prc配置下 所以加上八小时,所以出现多八小时的情况。
    所以说不要随便复制网上的代码。
    原来以为是php的一个bug所以检测几个版本,后来发现去掉“GMT”后正常了.
    -----------
    提问:为什么要在代码加上这个,apache或其他服务器本来不是有判断自己返回?
    回答:前面提到apache服务器对待动态页面和html的不一样,不会自动加上Last-Modified返回给浏览器,加上用户不停刷新(或按F5),那apache则只解析运行到上面段代码后停止,返回304给浏览器,浏览器用回缓存。
    适合范围:一般在php文件里这段代码和expires头域一起用,这样既能在浏览器端减少发请求,也能在服务器端减少运行代码量从而提高性能。
    值得一提:此方法在服务器集群的时候仍然适合使用,这个是Etag和if-none-match的鸡肋来的。
    (3)使用Etag和if-none-match头域的缓存
    Apache对于etag头部是默认开启的,且会给html、js、css等静态文件自动返回,动态如php文件默认没有,像Last-Modified一样需要加上代码。
    不同服务器返回的etag格式不同。
    Apche默认FileETag INode Size MTime来设置etag包含的内容。
    1)INode表示文件的索引节数被包含在内
    2)Size表示文件的字节数被包含在内
    3)MTime表示文件的最后修改时间包含在内
    4)All表示包含INode Size MTime
    5)None表示如果一个文档是基于文件的,不在回应中包含任何ETag域
    如“50000000536da-311-488a45c786210” 50000000536da是INode,311是字节数,488a45c786210是MTime
    注意
    如果包含INode Size MTime三者,不管“FileETag INode Size MTime”语句3个顺序如何,apache生成的顺序都是按照 INode-Size-MTime顺序
    常见代码

    1. if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && ($_SERVER['HTTP_IF_NONE_MATCH']==date('Y-m-d H:i',time())))
    2. {
    3.   header("HTTP/1.1 304 Not Modified");
    4.   exit();
    5. }
    6. header('Etag:'.date('' Y-m-d H:i '', time()));

    以上代码就是last-modified的复制,last-modified能用到的时候上面代码可以用。
    适用范围:动静态页面,单服务器模式。不适合集群服务器.
    是否矛盾:前面说last-modified在集群的时候可以用,又说不适合集群服务器,岂不是矛盾,那就要看etag的鸡肋
    如一个站有两台server1和server2两台服务器,假如php文件中没上面代码(有的话就是last-modified的复制了)
    1)在负载均衡的情况下首先server1处理静态文件是否自动返回了etag值10000000536db-44c2-4cd59ff9c752c
    2)然后第二次请求时候负载均衡到server2,因为第一次的时候server2并没有记录到10000000536db-44c2-4cd59ff9c752c这个值,所以不能判断而是生成属于自己的etag值,这样etag值10000000536db-44c2-4cd59ff9c752c起不了作用了。如果服务器集群很庞大的时候就成了鸡肋了。
    但是如果自动加上上面的代码,不过那台服务器处理,还是要执行代码,所以起作用了。

    二、    利用apache服务器端缓存和加速
    (1)启用apache缓存模块mod_expires
    启用动态加载模块mod_expires.so,启用该模块apache会根据你设定的配置规则返回相应expires和cache-control头域,相当于代码: header('Expires:'...); header('Cache-Control: max-age=second ');
    优点:
    1)比起last-modified和etag头域减少http请求,从而减服务器和宽带负担
    2)可以适用服务器集群,并没有etag鸡肋问题
    示例代码例说:
    在apache配置文件httpd.conf中加入:

    1. LoadModule expires_module modules/mod_expires.so
    2. ExpiresActive On
    3. ExpiresByType text/css "access plus 1 seconds"
    4. ExpiresByType tex/html "access plus 1 minutes"
    5. ExpiresByType application/javascript "access plus 1 hours"
    6. ExpiresByType application/x-javascript "access plus 1 days"
    7. ExpiresByType image/gif "acess plus 1 months"
    8. ExpiresByType image/png "acess plus 1 months"
    9. ExpiresByType image/jpeg "acess plus 1 months"
    10. ExpiresByType image/x-jpeg "acess plus 1 months"
    11. ExpiresByType application/x-shockwave-flash "acess plus 1 months"

    其中
    LoadModule expires_module modules/mod_expires.so 动态加载缓存模块mod_expires.so;ExpiresActive On表示激活缓存
    access表示允许缓存
    plus表示后面必须是整数
    seconds、minutes、days、months、years就不用说了,还有单位单复数要求不严格
    还有3种语法:
    1)ExpiresByType text/css "a60"相当于ExpiresByType text/css  "access plus 1 minute"
    上面代码按照这种语法如下:

    1. LoadModule expires_module modules/mod_expires.so
    2. ExpiresActive On
    3. ExpiresByType text/css a1
    4. ExpiresByType tex/html a60
    5. ExpiresByType application/javascript a3600
    6. ExpiresByType application/x-javascript a86400
    7. ExpiresByType image/gif a2678400
    8. ExpiresByType image/png a2678400
    9. ExpiresByType image/jpeg a2678400
    10. ExpiresByType image/x-jpeg a2678400
    11. ExpiresByType application/x-shockwave-flash a2678400

    2)ExpiresByType text/css "m60"表示文件最后修改的60秒过期,m等同于modification

    1. ExpiresByType image/jpeg "modification plus 1 months"

    3)ExpiresDefault这个表示默认文档类型文件缓存

    1. ExpiresDefault "access plus 1 days"

    这种写法主要补上其他非文档类型的缓存
    服务器生成效果
    语句:

    1. ExpiresByType text/css "access plus 1 hours"

    服务器处理mime类型是text/css也就是css文件时,效果等同于php语句:

    1. header("Cache-Control:max-age=3600");
    2. header("Expires:". date('D, d M Y H:i:s GMT', time()+3600);

    浏览器端显示头域如下:

    1. Cache-Control: max-age=3600
    2. Expires: Fri, 09 Nov 2012 05:37:22 GMT

    注意事项
    1)Cache-Control: max-age=3600级别比Expires: Fri, 09 Nov 2012 05:37:22 GMT高,也就是浏览器检查到有max-age且有效会忽略Expires
    2) ExpiresByType text/js "access plus 1 days"对于js文件是不起作用的,其中text/js改成application/javascript
    3) ExpiresByType application/x-javascript "access plus 1 days"这个类型是mime非正规类型,有些网站用到,考虑代码移植性加上去
    4)ExpiresByType image/jpg "acess plus 1 hours"这样不起作用,其中的image/jpg应该改成image/jpeg,这里就不贴测试内容了。
    更多mod_expires 语法、作用域等信息查看手册:
    http://www.phpchina.com/resource/manual/apache/mod/mod_expires.html
    --------------------------------------------------------
    (2)启用apache header模块mod_headers
    mod_expires设置缓存是为每重mime文件设置缓存时间,多且烦,要简短的话则可以启用apache mod_headers模块,而且mod_expires设置效果只能等效于http头cache-control和expires头域,mod_headers则可以设置、更改、删除http头所有头域,范围更广。这里只讲mod_headers模块的header指令
    header指令格式:
    header set 头域value
    value的的格式根据头域而变化,请看下面一个例子
    在httpd.conf里加入

    1. LoadModule headers_module modules/mod_headers.so
    2. <FilesMatch ".(pdf|swf|js|css|gif|jpeg|jpg|png|flv|ico|html)$">
    3. Header set Cache-Control "max-age=604800"
    4. </FilesMatch>

    上面代码第一行表示服务器匹配客户端请求文件的后缀是pdf|swf|js|css|gif|jpeg|jpg|png|flv|ico|html则设置cache-control max-age=604800 让浏览器缓存这些文件1天
    当然还可以设置其他头域如:
    Header set Last-Modified  "Thu, 10 Jun 2010 03:10:14 GMT"
    Header set Expires  "Thu, 10 Jun 2012 03:10:14 GMT "
    优点
    1)可以任意增删改header头部
    2)设置代码简洁
    3)因为可以根据后缀设置,所以可以为动态页面设置头域名
    4)前面介绍到的etag、last-modified、和mod-Expires模块功能都可以涵盖(v5)
    缺点:
    Last-Modified, Expires不能动态变化,只能设定某个值,则需要人为的根据项目需求不断修改相应的值,没代码header('Expires:'.date('D, d M Y H:i:s GMT', time()+60));那么灵活。
    注意:因为apache匹配后缀,则像jpeg、jpe这些同mime类型的不同后缀文件都要填如filematch里面
    更多mod_expires 语法、作用域等信息查看手册:
    http://www.phpchina.com/resource/manual/apache/mod/mod_headers.html
    ---------------------------------------------------------
    (3)启用apache压缩模块mod_deflate
    在httpd.conf加入

    1. LoadModule deflate_module modules/mod_deflate.so
    2. <Location />
    3. # 插入过滤器,启用压缩
    4. SetOutputFilter DEFLATE
    5. # Netscape 4.x 有一些问题...
    6. BrowserMatch ^Mozilla/4 gzip-only-text/html
    7. # Netscape 4.06-4.08 有更多的问题,取消压缩
    8. BrowserMatch ^Mozilla/4.0[678] no-gzip
    9. # MSIE 会伪装成 Netscape ,但是事实上它没有问题,所以这里是修复
    10. BrowserMatch bMSIE !no-gzip !gzip-only-text/html
    11. # 不压缩图片
    12. SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
    13. </Location>

    监听http头会多一个头域:
    Accept-Encoding: gzip,deflate,sdch
    说明压缩有效了。
    优点
    减少宽带加快速度
    更多mod_deflate 语法、指令、作用域等信息查看手册:
    http://man.chinaunix.net/newsoft/Apache2.2_chinese_manual/mod/mod_deflate.html
    --------------------------------------------------------------
    (4)启用apache模块mod_cache
    前面提到的mod_expires和mod_headers(缓存部分)都是apache根据http协议返回相应的缓存头域(cache-control、Expires、etag、last-modified)给服务器,让客户端的浏览器使用缓存达到加速优化的效果,而mod_cache模块则是在apache端缓存数据从而达到优化的目的。前两者从客户端缓存考虑,后者是服务器端考虑。
    相比起来后者可以把同一页面user one 产生的缓存返回给user two
    mod_cache一般结合模块mod_mem_cache(基于内存缓存管理模块,把数据缓存进主存)或mod_disk_cache(基于磁盘的缓冲管理器,把数据缓存进磁盘)
    1)mod_mem_cache

    1. <IfModule mod_cache.c>
    2. #加载mod_mem_cache
    3. LoadModule mem_cache_module modules/mod_mem_cache.so
    4. <IfModule mod_mem_cache.c>
    5. #缓存folderName文件内容
    6. CacheEnable mem /folderName
    7. #内存缓冲大小这里是4G
    8. MCacheSize 4096
    9. #用最近最少LRU算法,简单说内存满了,则找出最近最少使用的缓存块写入新数据。memcache也是用该算法
    10. MCacheRemovalAlgorithm LRU
    11. #最大缓存对象个数,这里1000,如果缓存对象超过此值则根据相应算法(这里是LRU)移除一个来储存最新对象,此值必须大MCacheMinObjectSize
    12. MCacheMaxObjectCount 1000
    13. #最小缓存对象个数
    14. MCacheMinObjectSize 1
    15. #每个对象最大容量,这里是2G,大于此值的对象会被丢弃,此值该根据/foldername下
    16. MCacheMaxObjectSize 2048
    17. #每个对象最大缓存时间
    18. CacheMaxExpire 864000
    19. #每个对象默认缓存时间
    20. CacheDefaultExpire 86400
    21. #指定哪些内容不缓存,这里表示noCacheFolder文件夹内内容不缓存
    22. CacheDisable /noCacheFolder
    23. </IfModule>
    24. </IfModule>

    注意
    l  MCacheMaxObjectCount > MCacheMinObjectSize
    l  MCacheMaxObjectSize和MCacheMinObjectSize值的确定根据folderName里内容确定
    l  CacheDefaultExpire值需要根据web访问强度,峰值等影响因素,一般需要不断测试
    2)mod_disk_cache

    1. LoadModule cache_module modules/mod_cache.so
    2. <IfModule mod_cache.c>
    3. LoadModule disk_cache_module modules/mod_disk_cache.so
    4. <IfModule mod_disk_cache.c>
    5. #缓存数据目录
    6. CacheRoot D:/
    7. #缓存folderName文件内容
    8. CacheEnable disk /folderName
    9. #缓存目录的子目录层数,这里是4
    10. CacheDirLevels 4
    11. #缓存文件最大大小
    12. CacheMaxFileSize 333
    13. #缓存文件最小大小
    14. CacheMinFileSize 1
    15. #缓存文件名长度
    16. CacheDirLength 3
    17. </IfModule>
    18. </IfModule>

    更多查看手册:
    http://man.chinaunix.net/newsoft/Apache2.2_chinese_manual/mod/mod_cache.html

    三、    Php代码入手
    (1)css 背景图片尽量合成一张图,用background-image and background-position定位图片,从而减少http请求数,且避免css表达式尽量避免。
    (2)css文件放在页面的前面,js文件放在后面。很容想到css是布局用得,让用户最先看到网页的内容js一般是内容齐全后才用到。这样用户觉得速度快很多,加载js的时候网页的布局已经好了,虽然事实上不是。
    (3)ajax如果不是大数据,多cookies不用用post而是用get,因为post会发送两次tcp包,第一个发送头部,第二个才是内容。
    (4)$bloger=$benwin. 'phpben.com ';代替$bloger="$benwin phpben.com";
    (5) if ("" == $var)代替if ($var == "")
    (6)explode()代替split()
    (7)$len=count('benwin');for($i=0;$i<$len;$i++)代替for($i=0;$i< count('benwin');$i++)
    (8)正则匹配尽量少用“*”
    (9)$i+=1;代替$i=$i+1;
    (10)if(!isset($bloger{5}))代替if(strlen($bloger)<5)
    (11)echo $bloger, ':', 'benwin';代替echo $bloger. ':'. 'benwin';
    (12)避免重复代码,写成一个函数调用
    (13)手动unset释放内存,特别是大数组,大对象,及时unset,而不是等脚本执行完自动回收
    (14)数据库连接用完记得关闭
    (15)抑制错误符号@尽量少用
    更多可以看看:
    雅虎优化35条:http://developer.yahoo.com/performance/rules.html  (非永久)
    Php性能测试:http://maettig.com/code/php/php-performance-benchmarks.php (非永久)

    四、    建立文件缓存

    文件缓存在某种程度上有点想apache mod_disk_cache模块,一般都包缓存写在磁盘文件里,等用户访问的时候先判断是否存在缓存,存在者直接读取缓存返回,否则则写入新的缓存。不同的mod_disk_cache是这些事情读取操作apache帮你完成,而这里说的文件缓存是需要程序员按照自己根据程序功能,以自己的经验,熟悉的算法规划出一定的缓存机制。
    现在不同公司都会自己写自己的文件缓存机制,包括一些大开源php系统比如phpcms、ecshop、phpwind、dedecms等,导致在php文件缓存机制方面没什么统一(smarty算统一一个)如ecshop改写smarty的缓存机制,phpcms只要三个类库pc_base 和cache_factory cache_file_class.php
    (1)文件缓存机制一般需要考虑的几个环节
    写(write_cache),读(read_cache),删(delete_cache),重写(rewrite_cache)
    (2)要考虑的几个问题:读写涉及的文件唯一,数据锁定,缓存时间
    1)单目录文件缓存,网站中所有静态页面(html),动态页面(sort.php?id=11)都保存在一个页面。为了方便读取,相互缓存文件之间的文件名必须唯一,第一时间想到md5(url)加密后作为文件名,或则自己写一个hash算法生成文件名。文件名是否有点长?
    2)多层目录文件缓存
    这种比较常见,一般根据不同模块,不同分类来建立缓存目录,然后这里肯定涉及到配置问题,读写的时候根据哪个目录,这时你的缓存类就需要配置、路径转换等问题了。
    Module1/sort.php?id=11这样的路径则可以把缓存写入Module1文件夹的sort_11.php
    3)锁定一般用到互斥锁,读不能写,写不能读
    4)设置缓存时间。
    在读的时候判断缓存文件什么时候创建(或最后一次修改),和当前时间相比如过期则重新生成缓存。还有一种方法是把缓存过期时间写入缓存文件的第一行或最后一行,读取内容是截取出来判断
    5)数据完整性
    笔者再做ecshop开发的时候曾经遇到缓存文件在写入的时候没完整写入(系统崩溃、断电等原因),读出来的数据肯定是不完整。解决这问题一种方法可以加入类型mysql redo的机制,专门用一个文件保存写入的信息包括写入时间,路径,内容,缓存时间,是否完整写入,否则重写入。还有一种笔者较喜欢的是,可以在写入文件末尾加上一个“判断量”比如加上“[phpben.com]”,在读取的时候先判断文件是否有该变量,有则是完整的,否者则删除或重写。后一种方法没那么复杂,容易实现。
    (3)实现环节简述
    这里是简单说下流程,没具体实现,具体实现可以googel以下或看开源系统(一般穿插很多内容)
    1)配置环节,set_config,主要是一些缓存路径path,默认缓存时间,是否开启互斥锁等操作function set_config (path=defaultPath,expire=defaultTime,isLock=ture,…)
    2)have_cache(fil_name)用于调用时判断文件中是否有缓存,有则通过read_cache读取缓存,否则执行文件且写入缓存write_cache
    3)写环节(write_cache),判断文件是否存在,不存在则创建(注意权限),根据规则生成缓存文件的名字(同目录下必须唯一),具体算法可以md5(url),sort.php?id=11改成sort_11.php等等。内容中是加入缓存时间,加入完整写入判断,当然肯定写入缓存内容。锁是否锁定等
    function write_cache(filName,filContent,expire,…)
    4)读环节read_cache,按照规则生成文件名和路径,锁定文件,读取文件,判断文件是否过期,过期则删除,否则继续判断文件是否是完整写入文件(很多没这个功能),完整则返回数据,否则返回
    functions read_cache(filName,…)
    5)重写环节,更新了数据则需要重写,和写环节一样,一般触发此环节都是人为触发。
    上面说的是实现环节
    ps:具体缓存机制时函数名肯定是花样百出,还有许多细节东西是写不出来的,这也是问什么文件缓存并没有设计模式哪有有统一的模式的原因。

    五、    优化Mysql加速
    关于mysql可以看笔者另外一篇文章:http://www.phpben.com/?post=74

    六、    Memcache和Redis
    这两个篇幅太大了且很重要的缓存模块,笔者以后会独立总结和介绍。
    至于那个比较好和趋势:
    引用黑夜路人前辈的一句话(此话鸟哥也转发):
    “在互联网开发领域,Redis + MongoDB (MySQL) 的模式正在逐步取代Memcached + MySQL 的模式,就像曾经Apache + PHP(mod_php) 的模式逐步已经被Nginx + PHP(php-fpm) 在取代一样,这个是技术历史发展的逐步行进”
    七、    Opcode加速器
    有了解过php源码的会知道,Zend引擎执行php代码经过以下阶段
    说明: C:UsersBenwinDesktop3333.jpg
    而php每次执行都要经过这些步骤,然后opcode加速器(缓存)就产生了,从而加快速度。
    老实说,笔者本着专研的精神,以后在这方面可是要加把劲了(^_^)。ps:图片来自鸟哥博客。
    现在比较多的加速器有:apc、Xcache、eAccelerater、facebook开发的HipHop VM
    八、    LVS、TFS、BFS、Hadoop
    自己搜索一下这些关于调度、集群、分布式的资料。

    参考资料:
    http://man.chinaunix.net/newsoft/Apache2.2_chinese_manual/mod/mod_cache.html
    http://man.chinaunix.net/newsoft/Apache2.2_chinese_manual/mod/mod_deflate.html
    http://www.phpchina.com/resource/manual/apache/mod/mod_expires.html
    http://maettig.com/code/php/php-performance-benchmarks.php
    http://developer.yahoo.com/performance/rules.html

  • 相关阅读:
    20170803 Airflow自带的API进行GET 和POST动作部分内容
    20170731 培训Bootstrap
    20170728 Celery项目 后台处理SQL SERVER的一个异常
    python 之 递归
    编译型语言和解释型语言的区别
    如何在命令行中让python2和python3同存
    bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+dijkstra
    单调栈题目总结
    汕头市队赛SRM15
    codevs 1269 匈牙利游戏——次短路(spfa)
  • 原文地址:https://www.cnblogs.com/gxldan/p/4066876.html
Copyright © 2011-2022 走看看