美文网首页PHP高级技能
缓存随谈系列之三:动态缓存

缓存随谈系列之三:动态缓存

作者: 我叫乔帮主 | 来源:发表于2017-05-10 21:07 被阅读908次

    作为缓存系列的最后一篇,也是我重点想要介绍的。

    • 缓存随谈系列之一:数据库缓存
    • 缓存随谈系列之二:静态缓存(使用静态缓存提升网站性能的五种方法)
    • 缓存随谈系列之三:动态缓存

    背景是这样的,在两会期间,我们参加了新华社新闻推送方面业务的运维保驾护航。在这方面我们遇到一个很棘手的问题,就是热点类新闻推送,是高并发应用场景,如同电商的秒杀应用。瞬时的热点新闻访问,高并发的场景给数据库缓存及数据库带来了极大的负荷。针对这种场景(采用nginx+php部署的后端应用,前端为手机app客户端),我们采用了动态缓存技术,单机处理能力从50tps提升到5000tps。所以对此技术场景进行了整理,就有了一种想要分享的冲动,本来主要针对动态缓存来进行分享。整理了一下相关的缓存技术,结合数据库缓存、静态缓存(使用静态缓存提升网站性能的五种方法)、动态缓存组成了缓存系列。

    何为动态缓存?即对动态页面的缓存。如,对 .do、.jsp、.asp/.aspx、.php、.js(nodejs)等动态页面缓存。可以看出,动态页面一般都会涉及动态计算、数据库缓存、数据库操作,所以每一次访问同一个页面,所获得的数据可能都有所不同。所以如若对数据及时性要求较高的应用,可能不太适合动态缓存。比如,对一个动态页面缓存了半个小时,用户请求访问该动态页面,返回缓存中的数据。很有可能,缓存中的页面数据即半个小时前缓存的页面数据状态。所以,动态缓存,是牺牲数据的及时性换取性能的技术。具体缓存设置多长时间,这个根据业务情况而来。

    一、 nginx动态缓存的原理概要

    nginx的动态缓存主要通过反向代理(http的负载均衡)实现,所以基本上可以实现所有动态页面的缓存,当然静态页面也能缓存(在上一个系列中已分享过通过nginx实现静态缓存的方式)。
    架构原理图如下图1:


    图1

    如上图所示,nginx做负载均衡反向代理,将用户请求转发至后端服务器。我们可以在nginx这层根据规则设置动态/静态缓存,即每次客户请求,直接由nginx将缓存数据返回,而不用再到后端获取响应数据。
    Nginx动态缓存核心配置(以缓存jsp为例):

    #levels设置目录层次 
    #keys_zone设置缓存名字和共享内存大小 
    #inactive在指定时间内没人访问则被删除在这里是1天 
    #max_size最大缓存空间
    proxy_cache_path /alidata/www/default/cache_dir/ levels=1:2  keys_zone=cache_one:200m inactive=1d max_size=30g;
    server {
        listen       80;
        server_name  _;
        location /{
               proxy_pass http://10.117.39.67:8080;
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
    
        location ~ .*\.jsp$
        {
               proxy_cache cache_one;                    # keys_zone后的内容对应
               proxy_cache_valid  200 304 301 302 10d;   #哪些状态缓存多长时间  
               proxy_cache_valid  any 1d;                #其他的缓存多长时间  
               proxy_cache_key $host$uri$is_args$args;   #通过key来hash,定义KEY的值
              
               proxy_pass http://10.117.39.67:8080;
               proxy_set_header   Host             $host;  
               proxy_set_header   X-Real-IP        $remote_addr;  
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;  
        } 
       
       access_log  /alidata/nginx/logs/default-cache.log;
    }
    

    以上配置在上一篇介绍静态缓存的时候,有看到类似配置。其实对于nginx而言,动态缓存和静态缓存的配置基本一致。唯一的区别就是,静态缓存的location配置中,正则匹配的是静态访问请求。而动态缓存的location配置中,正则匹配的是动态访问请求。

    二、 案例一:nginx对jsp的动态缓存

    在MyEclipse中,新建一个test的web项目,然后在默认的index.jsp中简单输出测试文字、当前日期 及一张图片。index.jsp测试代码明细:

    <%@ page language="java" import="java.util.*,java.text.SimpleDateFormat,java.text.DateFormat" pageEncoding="utf-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>This is test page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
      </head>
      <body>
        This is my JSP page. <br>
        ![](eg_tulip.jpg)<br>
        <%
          Date date = new Date(); 
          DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
          out.print("Now the time is :" + df.format(date));
        %>
      </body>
    </html>
    

    然后我们部署到tomcat中,且前端用nginx做反向代理,部署结构如下图2:


    图2

    为了测试方便,在后端仅部署了一台test tomcat。Nginx反向代理的配置如下:

    server {
        listen       80;
        server_name  _;
        location /{
               proxy_pass http://10.117.39.67:8080;
               proxy_set_header   Host             $host;
               proxy_set_header   X-Real-IP        $remote_addr;
               proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
       access_log  /alidata/nginx/logs/default-cache.log;
    }
    

    每次刷新浏览器我们可以看到显示的时间都是不一样的(如下图3):

    图3
    然后我们对jsp进行动态缓存,核心配置如下图4:
    图4
    这个时候我们通过浏览器访问对应jsp的页面,我们可以看到每次访问,页面显示的时间是一模一样的,由此可见我们nginx的动态缓存功能已经实现。

    我们在nginx的服务器中缓存目录可以看到针对刚才访问jsp的缓存文件,直到缓存时间到期,nginx将会一直将存放本地缓存的磁盘文件内容,作为response返回给客户端请求(如下图5):


    图5

    三、 案例二:nginx对php的动态缓存

    Nginx 对php的动态缓存,和Nginx对jsp的动态缓存配置基本一致,唯一不同的是才location中匹配php类型即可。由于篇幅有限,nginx对php的缓存就不再细节性的介绍。

    四、 php的动态缓存(fastcgi_cache)

    除了nginx的动态缓存外,php也有自带缓存(如fastcgi缓存)来实现动态缓存。实现原理架构图如下图6:


    图6

    Nginx的核心配置如下,值得注意的是,这里不需要通过反向代理来设置。是通过FastCGI自带的缓存来实现配置(如下图7):


    图7
    Php的测试代码如下(输出文字、日期及一张图片):
    图8

    通过浏览器多次访问我们的test.php页面,所以看到此页面的内容是不变的:


    图9
    同时我们在服务器中可以看到存放在磁盘中的缓存文件:
    图10

    直接缓存到期,或者我们手动清理缓存文件,则客户端才会收到最新的数据返回,否则将返回本地缓存的数据。

    我为自己带盐,原创作者:乔锐杰

    相关文章

      网友评论

        本文标题:缓存随谈系列之三:动态缓存

        本文链接:https://www.haomeiwen.com/subject/mkxntxtx.html