WCF4.0 –- RESTful WCF Services (5) (缓存)

缓存是Web开发中的重要技术,在开发RESTful服务也需要重视。合理的利用缓存可以大大提高服务的响应能力。从技术实现上,有客户端缓存和服务端缓存两大部分组成。而无论在哪边进行缓存,都需要一些数据来比较是否过期,Http协议中控制缓存的规则有:Cache-Control, ETag, Expires, Last-Modified。Expires是一种无条件缓存(通过过期时间控制),Last-Modified,ETag是一种有条件缓存(通过数据的标识(时间或者ID)来控制。

如果是无条件缓存客户端浏览器会检查Expires过期时间判断是否发出请求,如果是有条件客户端缓存,则会提交Last-Modified-Since或者ETag供服务端检查是否发生变化,返回304(Not Modified)提示客户端查询的数据没有变化,这需要客户端自己保留缓存。如果是服务端缓存,则返回200(OK)但数据从服务端自己的缓存中读取。另外通常说的缓存策略主要是针对查询即GET操作而言的。

不同的缓存策略有不同的适用场景,对于WCF REST来说客户端缓存需要在客户端额外的控制编码。服务端缓存则要考虑数据量尽量只对共享数据进行缓存,如果对于每个客户端的私有数据都缓存对存储空间来说是一个考验。

来看看有条件客户端缓存的示例:
服务端提供一个 GetTasks 方法,返回 Task 数组。一个 AddTask 方法,添加Task。每次添加Task都会修改_lastModifed(DateTime)

通过浏览器连续调用2次:http://localhost:52533/Service1/tasks 用 Fiddler 拦截可以看到
第一次返回200, 第二次返回304而且没有Response Body (hoho,这样网络传输的代价也减少了)
上面的代码中:CheckConditionalRetrieve 方法的一个重载接受上次修改的日期并根据请求的 If-Modified-Since 标头检查该日期。如果该标头存在并且自该日期以来尚未修改资源,将引发 WebFaultException 并返回 HTTP 状态代码 304。而 CheckConditionalRetrieve 之后的“查询操作”(return _tasks)实际也就没有进行。




上面只是浏览器的行为结果,下面看看客户端如何模拟调用:
Tip: WebClient 中对于 Last-Modified-Since 有限制,因此无法使用 WebClient.Headers.Add() 方法来添加头信息。(会抛出异常)

这段代码从Response里取得 Last-Modified,并添加到下一次请求的 Last-Modified-Since 中,如果服务端检查发现数据没有变化,则在 GetResponse() 时抛出 WebException (No Modify)。很显然这需要我们自己在客户端维护这样的数据,以便在发现 No Modify 时可以使用。
这无疑会加大客户端编码的复杂程度,我想实际运用时也可以把“数据没有发生变化”的异常抛给UI直接显示。

这里又引申出服务端缓存的概念,客户端无论如何都希望获得200(OK)的Response。在 WCF 4.0 里利用 ASP.NET 服务的兼容模式,还可以利用 [AspNetCacheProfile] 特性。上面的 GetTasks 方法修改如下:

CacheFor5Seconds 对应的在 Web.config 中加上配置:

缓存配置文件中最重要的特性是 cacheDurationvaryByParam。这两个特性都是必需的。cacheDuration 设置应缓存响应的时间(以秒为单位)。使用 varyByParam 可指定用于缓存响应的查询字符串参数。对于使用不同查询字符串参数值发出的所有请求,将单独进行缓存。例如,对 http://MyServer/MyHttpService/MyOperation?param=10 发出初始请求后,使用同一 URI 发出的所有后续请求都将返回已缓存的响应(只要缓存持续时间尚未结束)。对于形式相同但具有不同参数查询字符串参数值的类似请求的响应,将单独进行缓存。如果不需要此单独缓存行为,请将 varyByParam 设置为“none”。

客户端:
 
为了证明服务端缓存的效果,我在1次GetTasks()之后,执行一次AddTask(),再每隔1秒进行一次GetTasks()连续两次,再隔4秒进行一次GetTasks()。这样,前3次都在AddTask()之后5秒内查询,最后一次是在AddTask()之后第6秒查询。 

运行结果:

可以看到,虽然AddTask成功了,但是在缓存期内,服务端并没有真正的执行“查询操作"(return _tasks),返回的只是缓存数据。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值