ASP.NET Web Api使用CacheCow和ETag缓存资源

ASP.NET Web Api使用CacheCow和ETag缓存资源

ASP.NET Web Api使用CacheCow和ETag缓存资源
2015-07-15 FZRAIN dotNET跨平台
前言
本文将使用一个开源框架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再次请求服务器:
所以结果:
这个响应告诉客户端:”你手里的资源不是最新的,先拿到最新的资源我才让你修改”。
原文链接:http://www.cnblogs.com/fzrain/p/3618887.html

posted on 2018-08-11 14:36 micwin 阅读(...) 评论(...)  编辑 收藏

转载于:https://www.cnblogs.com/chinanetwind/articles/9459710.html

ASP.NET Web Api使用CacheCow和ETag缓存资源相关推荐

  1. ASP.NET Web Api 使用CacheCow和ETag缓存资源(转载)

    转载地址:http://www.cnblogs.com/fzrain/p/3618887.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的缓 ...

  2. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【十】——使用CacheCow和ETag缓存资源...

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的 ...

  3. ASP.NET Web API中的参数绑定总结

    ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...

  4. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程

    最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...

  5. (四)Asp.net web api中的坑-【api的返回值】

    (四)Asp.net web api中的坑-[api的返回值] 原文:(四)Asp.net web api中的坑-[api的返回值] void无返回值 IHttpActionResult HttpRe ...

  6. WCF 和 ASP.NET Web API

    地址:https://docs.microsoft.com/zh-cn/dotnet/framework/wcf/wcf-and-aspnet-web-api WCF 是 Microsoft 为生成面 ...

  7. ASP.NET Web API自身对CORS的支持:从实例开始

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中我们通过自定义的HttpMessageHandler为ASP.NET Web API赋予了跨域资源共享的能力,具体来 ...

  8. ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API

    本篇尝试在现有的ASP.NET MVC 4 项目上增加使用ASP.NET Web API. 新建项目,选择"ASP.NET MVC 4 Web应用程序". 选择"基本&q ...

  9. [转]Web API Introduction to OData Services using ASP.NET Web API

    本文转自:http://mahedee.net/tag/web-api/ What is OData? OData Stands for Open Data Protocol. It is a dat ...

最新文章

  1. 【布局】圣杯布局双飞翼布局
  2. SpringMVC_实现简单的增删改查
  3. 如何用css和HTML结合画熊,结合伪元素实现的纯CSS3高级图形绘制
  4. 实现文件中名词的统计计数_通过勤哲EXCEL和Excel中的rank函数实现排名统计
  5. Jedis与Redisson对比有什么优缺点?
  6. Google在东京召开了一场AI座谈会
  7. gitlab之 修改默认的仓库存储目录及数据迁移
  8. C++小白课本练习5
  9. 集训8.16最小生成树讲解
  10. ajaxFileUpload 异步上传文件简单使用
  11. 贷前调查必须采集的十大客户信息
  12. 关于传奇客户端及补丁文件相关合集
  13. 百度地图、腾讯地图坐标转换
  14. [UE4]Viewport中摄像机镜头缩放速度修改
  15. 听说你要找前端工作,写一个酷炫的动画的简历呀
  16. 用SVM预测股票涨跌
  17. ROS 学习踩坑笔记5-Intel D435相机不发布点云,在RVIZ中,不显示点云(wants topic /image/compressed to have datatype/md5sum)
  18. 2020面试要点大全
  19. 1-9DCL语言与提权逻辑
  20. [Practical.Vim(2012.9)].Drew.Neil.Tip03 学习摘要

热门文章

  1. java tr069_tr069cpe模拟器 针对tr069协议的客户端简单实现 - 下载 - 搜珍网
  2. 代码写春联【js+html版本与python版本】
  3. oracle 查找表列名,oracle查询列名(查询表字段名称)
  4. 安卓模拟器手动root
  5. 图形学基础笔记I:直线和圆的光栅算法、中点线算法、中点圆算法
  6. 有刷与无刷电机的原理
  7. 一文了解互联网中的产品经理
  8. vue组件之间数据传递和通信方式总结
  9. matlab选修结课作业,matlab结课作业
  10. 如何使用 Python 实现彩票自由(双色球)