ASP.NET Web Api 使用CacheCow和ETag缓存资源(转载)
转载地址:http://www.cnblogs.com/fzrain/p/3618887.html
前言
本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的缓存。
使用缓存技术可以很好的提高Web Api的性能,减小服务器的开销。我们把这种缓存形式称之为:条件化请求(Conditional Requests)。具体表现为:客户端向服务器请求时会附加一个请求头ETag,然后服务器会根据这个信息来决定是否需要把更新过的资源响应给客户端,如果需要,则响应200状态吗以及资源内容,否则响应304状态码(Not modified)以及一个空的响应正文。
什么是ETag?
写了好多,那么什么是ETag呢?ETag是服务器为特定资源生成的一个唯一标识(string类型)。你也可以理解为用来检查服务器资源是否变化。
ETag分2种类型:强类型和弱类型。对于弱类型的ETag包含一个前缀W(例如:W/53fsfsd322),而强类型的ETag不包含任何前缀(例如:53fsfsd322)。通常来说,弱类型ETag代表缓存短时间资源(内存缓存),而强类型的ETag缓存是靠持久化的方式来实现的。
ETag工作原理
先上一张图:

由上图可知:在一开始,客户端发起一个Http Get请求,请求的是id为4的course资源,由于这个资源是第一次被访问,因此服务器在把资源返回的同时附加了一个响应头(ETag)。
现在,客户端发送Http Get请求想要再次请求相同的资源(Course id: 4),考虑到客户端使用缓存,因此Get请求初始化的时候增加一个Header(If-None-Match),内容就是资源的ETag值。当服务器接受到请求的时候,就会读取ETag的值并与服务器内的ETag值做比较,如果完全相同,服务器就会返回304状态码(Not modified)并且正文不含任何内容。这样客户端就知道资源是最新的。
对于Http Get和Delete请求,我们可以使用(If-None-Match)头,但对于更新时我们要使用(If-Match)来匹配Put/Patch请求。请求到达的时候,服务器会校验ETag值,如果不一样,服务器就会响应一个412状态码(Precondition Failed),因此客户端就知道自己的版本不是最新的,在客户端没有获取最新资源之前是不允许更新的。
在Web Api中配置CacheCow
经过了之前的一段简单介绍,我们来实现所谓的“条件化请求”。
我们需要使用NuGet来安装CacheCow,打开NuGet控制台,输入“Install-Package CacheCow.Server -Version 0.4.12”。会安装2个dll:CacheCow.Server和CacheCow.Common。
配置CacheCow也是非常简单的,我们所需要做的是创建一个Cache Handler并把它注入到web api的请求管道中。这个handler就是在请求到达和离开web api的时候检查ETag和生成ETag的。
为了实现这一点,在“WebApiConfig.cs”里做如下配置:
//Configure HTTP Caching using Entity Tags (ETags)
var cacheCowCacheHandler = new CacheCow.Server.CachingHandler();
config.MessageHandlers.Add(cacheCowCacheHandler);
到目前为止,我们的web api已经具有使用本机内存实现缓存的功能了,这也是CacheCow默认的配置,在单机状态(只有一台服务器)的时候可谓是比较完美了。然而,当应用程序走向分布式的时候就出现为题了——由于不同的web服务器需要共享缓存状态,因此我们需要把缓存状态持久化到一个单独的地方(SQL Server, MongoDB, MemCache)。但是在实现持久化之前我们先测试一下内存缓存。
打开我们的测试客户端PostMan(chrome插件),发送Get请求到:http://localhost:{your_port}/api/courses/4

结果:

请求注释:
1.响应Http状态码是200,意昧着服务器把资源一起响应过来了。
2.这次响应增加了2条头信息:ETag和Last-Modified,目前我们只需关心ETag的值,因为下次请求会用到。
3.ETag的类型是弱类型的(带有W前缀),说明这个缓存存在于服务器的内存中,如果重启IIS或切断服务进程的话,缓存就会失效。
对于接受到ETag值的客户端,在下次请求相同资源的时候就需要附加一个“If-None-Match”的请求头,服务器就会比较客户端与自己内存中的ETag值,如果相同,返回304(Not modified),不相同则返回200加上资源内容。
测试:我们再次请求这个资源

结果:

对于这次请求来说:
1.http状态码是304,意味着客户端的资源是最新的,因此响应body是空的
2.客户端得到相同的ETag值
在SQL Server端实现缓存
在SQL Server中做缓存同样很简单,首先我们要确定在哪个持久化介质中实现缓存,我们用的是SQL Server,因此打开NuGet控制台,输入如下命令:Install-Package CacheCow.Server.EntityTagStore.SqlServer -Version 0.4.11。
然后在“WebApiConfig”做如下配置:
//Configure HTTP Caching using Entity Tags (ETags)
var connString = System.Configuration.ConfigurationManager.ConnectionStrings["eLearningConnection"].ConnectionString;
var eTagStore = new CacheCow.Server.EntityTagStore.SqlServer.SqlServerEntityTagStore(connString);
var cacheCowCacheHandler = new CacheCow.Server.CachingHandler(eTagStore);
cacheCowCacheHandler.AddLastModifiedHeader = false;
config.MessageHandlers.Add(cacheCowCacheHandler);
上面的实现很明显,CacheCow需要把缓存信息存到数据库中,因此我们需要制定我们api所用的数据库。然后把eTagStore实例赋给Cache handler。
如果你现在直接请求api的话,等待你的不是资源而是一个500错误码。这是因为之前我们介绍到CacheCow需要把缓存信息存入数据库,那么数据库中就应该有一张对应的表以及操作这张表的存储过程,因此我们需要执行一个sql脚本。这个脚本通常在“{projectpath}\packages\CacheCow.Server.EntityTagStore.SqlServer.0.4.11\script”
执行完这个脚本后,你会发现数据库多了一张表以及5个存储过程:

ok,可以测试了,还是刚刚的例子:


正如上图所示,ETag的值不再是弱类型的了,因此我们存到SQL Server中了,打开SQL Server中的CacheState表,你会发现:

现在,只要没有客户端来更新这个资源,之前访问过这个资源的客户端统统会得到304状态码以及空的body(前提是客户端的请求中包含ETag值,呵呵)。
现在我们实现一下更新,客户端要更新资源就需要包含一个“If-Match”的请求头,如下图所示:

结果:

ETag已经改变:

我们使用老的ETag再次请求服务器:

所以结果:

这个响应告诉客户端:”你手里的资源不是最新的,先拿到最新的资源我才让你修改”。
ASP.NET Web Api 使用CacheCow和ETag缓存资源(转载)的更多相关文章
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【十】——使用CacheCow和ETag缓存资源
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的 ...
- ASP.NET Web API通过ActionFilter来实现缓存
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using Sys ...
- 通过扩展让ASP.NET Web API支持W3C的CORS规范(转载)
转载地址:http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-04.html CORS(Cross-Origin Resource Shari ...
- ASP.NET Web Api构建基于REST风格的服务实战系列教程
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[十]——使用CacheCow和ETag缓存资源 系列导航地址http://www.cnblogs.com/fzrain/p/3 ...
- ASP.NET Web API中通过ETag实现缓存
通常情况下Server是无状态的,在ASP.NET Web API中,我们可以让服务端响应体中产生ETag属性,起到缓存的作用.大致实现原理是: 1.服务端的响应体中返回一个ETag属性2.客户端通过 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】
最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...
- ASP.NET Web API实现缓存的2种方式
在ASP.NET Web API中实现缓存大致有2种思路.一种是通过ETag, 一种是通过类似ASP.NET MVC中的OutputCache. 通过ETag实现缓存 首先安装cachecow.ser ...
- Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文主要来讲解以下内容: ...
- ASP.NET Web API中的参数绑定总结
ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...
随机推荐
- auto与decltype
今天搜狗笔试的一道选择题,原题给忘了,但记得所考的知识点.知识点很基础,但很容易忽视. 具体内容可参考C++ Primer. auto :变量取auto后,其所对应的类型 auto一般会 ...
- bug-android之INSTALL_FAILED_NO_MATCHING_ABIS无法安装在虚拟机
bug描述: 经常在网络上下载一些实例,自己研究 ,运行时不时会出现这个bug: Installation error: INSTALL_FAILED_NO_MATCHING_ABIS bug解决方案 ...
- 【转】【编码】ANSI,ASCII,Unicode,UTF8之一
不同的国家和地区制定了不同的标准,由此产生了 GB2312.GBK.GB18030.Big5.Shift_JIS 等各自的编码标准.这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称 ...
- ASC47B borderless
题目描述 border集合为{NULL,str}的串str称为borderless串. border即KMP里的那个. 字符集{'a','b'},给定长度n,求第k(给定)小的borderless串. ...
- LUA require 搜索路径指定方法
如果是一个 *.LUA 的文件, 里面用到了自己写的库, 或者第三方写的库, 但是你不想把它放到 lua 的安装目录里, 则在代码里面可以指定require搜索的路径. package.path = ...
- ubuntu dhcp修改ip地址
sudo vim /var/lib/dhcp/dhclient.eth0.leases 把里边的fixed-address都改成你想要的ip. 然后执行 sudo ifdown eth0 && ...
- 《Head First Servlet JSP》学习笔记一
- hadoop初识
搞什么东西之前,第一步是要知道What(是什么),然后是Why(为什么),最后才是How(怎么做).但很多开发的朋友在做了多年项目以后,都习惯是先How,然后What,最后才是Why,这样只会让自己变 ...
- effective OC2.0 52阅读笔记(二 对象、消息、运行期)
第二章:对象.消息.运行期 6 理解属性这一概念 总结:OC解决硬编码偏移量问题的做法,一种方案是把实例变量当做一种存储偏移量所用的特殊变量,交由类对象保管,偏移量会在运行期查找,叫做稳固的“应用程序 ...
- Effective C++ -----条款40:明智而审慎地使用多重继承
多重继承比单一继承复杂.它可能导致新的歧义性,以及对virtual继承的需要. virtual继承会增加大小.速度.初始化(及赋值)复杂度等等成本.如果virtual base classes不带任何 ...