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

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

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

背景是这样的,在两会期间,我们参加了新华社新闻推送方面业务的运维保驾护航。在这方面我们遇到一个很棘手的问题,就是热点类新闻推送,是高并发应用场景,如同电商的秒杀应用。瞬时的热点新闻访问,高并发的场景给数据库缓存及数据库带来了极大的负荷。针对这种场景(采用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

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 转自陈明乾的博客,可能有一定更新。 转原文声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、...
    C86guli阅读 4,667评论 6 72
  • 1. Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单...
    rosekissyou阅读 10,184评论 5 124
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 这种活法,很是愚蠢。 习惯了自我否定,对一切都不再自信,只想混混度日,但内心其实不甘平庸。 知道自己可悲,但抱歉,...
    浪迹_绝尘阅读 168评论 0 0