ASP.NET性能优化之局部缓存分析_实用技巧

在网站的开发过程中,经常碰到的一类需求场景是:

1:页面含热点新闻,热点新闻部分需要10分钟更新一次,而整个页面的其它部分1天内都不会变动;

2:首页的某个BANNER需要显式:欢迎***;

上面场景中的1,如果整个页面的缓存失效都定为10分钟,则势必增加性能开销,所以最好的策略是页面的不同部分采用不同的缓存失效时长。对于场景2也一样,我们不应该为了迁就某个BANNER不能应用缓存,就让整个页面都不支持缓存。

可以说,如果我们在开发网站过程中的缓存策略是不支持页面局部缓存的,整个架构就是不合理的。

一:局部缓存常用解决方案

针对上面的需求,有几类解决方案:

1、Client Side Includes(CSI):通过frame、iframe、 javascript、javacript+ajax等方式将另外一个页面的内容动态包含进来。像现在流行的jquery等javascript库对此有较好的支持。

优点:能够利用浏览器客户端并行处理及装载的机制;通过浏览器缓存机制可以降低网络传输时间,提高性能;计算放在客户端,能够降低服务器端压力

缺点:搜索引擎优化问题;javascript兼容性问题;客户端缓存可能导致服务器端内容更新后不能及时生效;XSS等安全隐患

2、Server Side Includes(SSI):

优点:SSI技术是通用技术,不受具体语言限制,只需要Web服务器或应用服务器支持即可,Ngnix、Apache、Tomcat、Jboss等对此都有较好的支持

缺点:SSI在语法上不能够直接包含其他服务器的url(当然也可以通过redirect等来变通实现),因此在需要充分利用缓存及负载均衡的环境下相对不是很灵活。

当然如果不使用单独的缓存服务器,而是使用Ngnix,利用Ngnix对SSI及Memcached支持,通过NginxHttpSsiModule、 NginxHttpMemcachedModule也可以实现页面缓存,但与专业的缓存服务器(例如Varnish)相比较,Ngnix作为缓存服务器只适合于中小规模的场合。

3、使用ASP.NET的片段缓存

可以利用用户控件将页面分段,在ascx文件中写入缓存的语句,而不在aspx文件中写缓存语句,这样ASP.NET就可以只缓存ascx片断的输出了。

缺点:片段缓存不支持Location特性;缓存页面片段惟一合法的地方是web服务器。这是因为片段缓存在ASP.NET中是新的功能,所以浏览器和代理服务器不支持。由于它不是W3C标准,像SQUID和VARNISH这样的代理服务器也不支持它。

4、Edge Side Includes (ESI):

Edge Side Includes(ESI) 和Server Side Includes(SSI) 和功能类似。SSI需要特殊的文件后缀(shtml,inc)。ESI可以直接通过URI包含远程服务器文件,ESI更适合用于缓存服务器上,缓存整个页面或页面片段,因此ESI特别适合用于缓存。本文要介绍的就是ESI的方式来支持局部缓存。

优点:ESI是一个W3C标准,被当下流行的缓存服务器SQUID,Varnish支持。

二:ESI的ASP.NET实现

本文所要阐述的是ESI局部缓存的实现。主页面(test1.aspx)前台:

复制代码 代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test1.aspx.cs" Inherits="WebApplication2.aspx.test1" %>
<%@ Import Namespace="System.Globalization" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<div>这里是局部缓存</div>
<esi:include src="test2.aspx"/>
<div>局部缓存结束</div>
<%=DateTime.Now.ToString("U", DateTimeFormatInfo.InvariantInfo)%>
</body>
</html>

主页面的后台请参看上篇,对主页面采取了缓存策略,即在页面中使用esi:include标识。
被包含的页面(test2.aspx)的前台:

复制代码 代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test2.aspx.cs" Inherits="WebApplication2.aspx.test2" %>
<%@ Import Namespace="System.Globalization" %>
<div>
局部缓存中的页面:
<%=DateTime.Now.ToString("U", DateTimeFormatInfo.InvariantInfo)%>
</div>

被包含的页面的后台什么也不需要处理,也就是不为它加入任何缓存策略,该页面是实时的。
VARNISH配置文件如下:

复制代码 代码如下:

backend default {
.host = "192.168.0.77";
.port = "80";
}
sub vcl_fetch {
remove beresp.http.Set-Cookie;
if(req.url ~ "test1.aspx") {
esi;
}
if(req.url ~ "test2.aspx"){
return (pass);
}
}
sub vcl_recv {
remove req.http.Cookie;
#remove req.http.Accept-Encoding;
#remove req.http.Vary;
}
sub vcl_hit {
if(req.http.Cache-Control~"no-cache"||req.http.Cache-Control~"max-age=0"||req.http.Pragma~"no-cache"){
set obj.ttl=0s;
return (restart);
}
return (deliver);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}

上文的vcl_fetch函数中加了两个判断,指的是:如果碰到test1.aspx就处理esi标识,如果碰到test2.aspx,就直接忽略让后台IIS处理。
值得注意的是,启动命令中加入了-p选项(这是一个varnish的小问题,请查阅参考,此处不表):
varnishd -a :8011 -T :8088 -f c:/varnish/etc/default.vcl -p esi_syntax=0x1 -s file,c:/varnish/var/cache,100M
三:效果
启动varnish后,我们发现,对于test2.aspx,由于我们使用了esi对其进行了包含,而test2.aspx又未进行缓存,所以在test1.aspx的缓存有效期内,随着每一次刷新,test1.aspx的内容没有变动,但是所包含的test2.aspx区域,会实时刷新。
参考(第一小节大部分来自参考文字):
https://www.varnish-cache.org/trac/ticket/352

http://cd34.com/blog/infrastructure/no-esi-processing-first-char-not/

http://hi.baidu.com/chuanliang2007/blog/item/075f67963e20f315d31b7035.html

http://www.w3.org/TR/esi-lang

时间: 2024-12-31 03:03:02

ASP.NET性能优化之局部缓存分析_实用技巧的相关文章

Asp.Net中索引器的用法分析_实用技巧

本文实例分析了Asp.Net中索引器的用法.分享给大家供大家参考.具体如下: 索引器定义类似于属性,但其功能与属性并不相同.索引器提供一种特殊的方法编写get和set访问器.属性可以像访问字段一样访问对象的数据,索引器可以使用户像访问数组一样访问类成员. 一.索引器特性 1.get 访问器返回值.set 访问器分配值. 2.this 关键字用于定义索引器. 3.value 关键字用于定义由 set 索引器分配的值. 4.索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制. 5.索引器可

ASP.NET深度复制和浅度复制分析_实用技巧

本文深入浅出的分析了ASP.NET深度复制和浅度复制.分享给大家供大家参考.具体分析如下: 之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉. 如果大家不懂值类型和引用类型的区别,请先看http://www.jb51.net/article/57471.htm,本来想自己写的,但刚好看到了这篇写的非常全面,就不自己写了. 大家都知道Object是所有类共同的基类,其有个方法是MemberwiseClone(),其用途为 我们可以通过这个方法来达到浅

ASP.NET中Dictionary基本用法实例分析_实用技巧

本文实例讲述了ASP.NET中Dictionary基本用法.分享给大家供大家参考,具体如下: //Dictionary位于System.Collections.Generic命名空间之下 /* * 使用Dictionary之前必须引用System.Collections.Generic命名空间: * 使用Dictionary时必须声明其键和值的数据类型(可以为任意类型): */ //声明实例化Dictionary为dic System.Collections.Generic.Dictionary

ASP.NET中Cookie的用法实例分析_实用技巧

本文实例讲述了ASP.NET中Cookie的用法.分享给大家供大家参考.具体分析如下: Cookie的用法也和ASP中差不多.比如我们建立一个名为aspcn,值为飞刀的cookie HttpCookie cookie = new HttpCookie["aspcn"]; cookie.Value = "飞刀"; Response.AppendCookie(cookie); 我们取出Cookie值也很简单 HttpCookie cookie = Request.Coo

asp.net程序优化 尽量减少数据库连接操作_实用技巧

项目以我自己的设计编码完成,并整合测试.初始化数据时,问题出现了.刚开始体现在客户端接受数据很慢.测试环境环境下,数据库服务器部署在国外,网站部署在公司内部,而且我一直认为我的程序在数据库数据处理这里已经做了足够的优化,包括索引和主键已经做到了合理使用.综上所述,起初的速度问题一直没有引起我的关注. 然而最后问题的关键恰恰出在数据库连接查询方面,频繁查询导致数据初始化速度很慢.刚开始我采取的方法是即用即查:需要数据的时候就从数据库查,有比较多的单表查询返回单个字段的情况.假如我有大概3000条左

ASP.NET+XML打造网络硬盘原理分析_实用技巧

常用传输方式及其在特定环境下面临的困难 我们经常有这样的应用需求:通过网络交换公共数据文件以实现资源共享,同时保护私有数据不被非法访问,并使用简单.直观的方式操作.我们常用的文件传输FTP.Email邮件.网上邻居都能实现文件的传送.其中,"Ftp"功能最为强大,但使用起来却稍显复杂,一大堆设置足以让许多人望而止步,尤其用户数量不可预见时,针对特殊需求用户的设置将更加繁琐:"Email"是大家所熟悉的了,但它的传送不仅需要你连入Internet,而且它的安全性也是个

asp.net 产生唯一随机码的方法分析_实用技巧

1. 自己写代码产生随机的数字和字母组合,每产生1个去数据库查询该随机码是否已存在,如果已存在,则重新产生,直到不重复为止. 优点:没发现有啥优点. 缺点:产生速度慢,还要查询数据库,当数据量大的时候,可能重复的机率会比较高,要查询多次数据库. 2. guid,该方法应该是用的比较多的. 优点:使用简单方便,不用自己编写额外的代码 缺点:占用数据库空间相对较大,特别是根据guid查询速度比较慢(毕竟是字符串). 3. 主键+随机码的方式,我们产生的随机码保存到数据库肯定会有个主键,用该主键+随机

asp.NET开发中正则表达式中BUG分析_实用技巧

比如以下的代码就是用来测试用正则表达式匹配从 0xff 到 0xffff 的字符.而值范围在 0 到 0xfe 的所有字符是不能被匹配的. 以下为引用的内容: 复制代码 代码如下: Regex regex = new Regex(@"[/u00FF-/uFFFF]+"); // The characters, whoes value are smaller than 0xff, // are not expected to be matched. for (int i = 0; i &

Asp.Net Couchbase Memcached图文安装调用开发_实用技巧

安装服务端 服务端下载地址:http://www.couchbase.com/download 选择适合自己的进行下载安装就可以了,我这里选择的是Win7 64. 在安装服务端如果发生如下所示的错误,我在win7 64安装的过程中就遇到了. 这个时候可以先撤销安装.通过CMD命令运行regedit.展开HKEY_LOCAL_MACHINE\Software\Microsoft\ Windows\ CurrentVersion分支,在窗口的右侧区域找到名为"ProgramFilesDir"