4

我有一个 WCF 服务,它缓存某些数据并使用它来响应 Web 请求。为了满足这个要求,我将服务设为单例(使用InstanceContextMode.SingleConcurrencyMode.Multiple(是的,它是线程安全的))。

我尝试使用以下绑定将服务的超时设置为最大值:

 <binding name="WebHttpBinding" receiveTimeout="24.20:31:23.6470000">
    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="None" />
    </security>
 </binding>

我的问题是服务实例以不可预知的时间间隔死亡,这意味着第一个 Web 请求命中将导致缓存被重建(一个非常慢的过程)。

理想情况下,缓存将在每天的固定时间重建,而不必受到 Web 请求的影响。我可以将应用程序池设置为在设定的时间回收,但这仍然无法解决服务直到第一个 Web 请求才被实例化的问题。我宁愿不必编写一个向服务发送请求的预定脚本,因为这有点骇人听闻。

在 WCF 服务中执行缓存是否有更好的策略?其他人在这里做了什么?有最佳实践吗?

4

5 回答 5

4

有一篇关于Caching Support for WCF Web HTTP Services的 MSDN 文章,摘录如下:

.NET Framework 版本 4 使您能够在 WCF Web HTTP 服务中使用 ASP.NET 中已有的声明性缓存机制。这允许您缓存来自 WCF Web HTTP 服务操作的响应。当用户向配置为缓存的服务发送 HTTP GET 时,ASP.NET 会发回缓存的响应并且不调用服务方法。当缓存过期时,下次用户发送 HTTP GET 时,会调用你的服务方法并再次缓存响应............

您可能还想看看:

于 2013-09-26T19:16:37.507 回答
1

我已经在 web 服务的更高层实现了缓存。

通过这种方式,您可以决定何时使缓存无效,以及何时从磁盘反序列化。

为了确保在第一个 webrequest 之前构建缓存,添加一些代码以global.asax在 web 服务器加载时生成缓存。

这比以“正确的方式”做要简单得多

[OperationContract]
public void GetLargeComplexData();

public GetLargeComplexData()
{
   // deserialize last cached data from db or file
   ...

   // Verify the deserialized cache is not invalid
   ...

   // if cache is invalid rebuild
   ...

   //return cached data
   ...
}
于 2013-09-26T18:51:34.590 回答
0

您可以使用的一个选项是将缓存移出 WCF 服务并移入专用缓存服务(例如Memcached )或使用Microsoft AppFabric 缓存

这允许您将缓存数据的存储与 WCF 服务分开,以便您在管理和访问数据的体系结构中拥有更多自由。

于 2013-09-26T19:16:59.337 回答
0

receiveTimeout不会影响您尝试执行的操作。您应该使用AppFabric来保持您的服务始终运行。这样,每当您回收时,AppFabric 都会自动预热您的服务。只需确保在实例化服务时构建缓存,而不是在首次访问时构建。

于 2013-09-26T18:51:44.207 回答
0

您可以使用 IIS7 应用程序预热模块

http://blogs.iis.net/thomad/archive/2009/10/14/now-available-the-iis-7-5-application-warm-up-module.aspx

于 2013-09-26T19:02:02.530 回答