我有一个WCF服务,用于缓存某些数据并使用它来响应Web请求。为了处理这个要求,我使服务成为Singleton(使用InstanceContextMode.Single
和ConcurrencyMode.Multiple
(是的,它是线程安全的))。
我尝试使用以下绑定将服务的超时设置为最大值:
<binding name="WebHttpBinding" receiveTimeout="24.20:31:23.6470000">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None" />
</security>
</binding>
我的问题是服务实例在不可预测的时间间隔内死亡,这意味着要访问的第一个Web请求将导致缓存重建(这是一个非常缓慢的过程)。
理想情况下,缓存会在每天的设定时间重建,而不会受到Web请求的影响。我可以将应用程序池设置为在设定的时间回收,但是这仍然无法解决在第一次Web请求之前未实例化的服务问题。我宁愿不必制作一个向服务发送请求的预定脚本,因为这有点像hacky。
在WCF服务中执行缓存是否有更好的策略?其他人在这做了什么?有最好的做法吗?
答案 0 :(得分: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时,将调用您的服务方法并再次缓存响应..........
您可能还想查看:
答案 1 :(得分:1)
我已经在webservice中的更高层实现了缓存。
通过这种方式,您可以决定何时使缓存无效,以及何时从磁盘反序列化。
要确保在第一次webrequest之前构建缓存,请在global.asax
添加一些代码,以便在加载Web服务器时生成缓存。
比“right way”
更简单[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
...
}
答案 2 :(得分:0)
receiveTimeout
不会影响您尝试做的事情。您应该使用AppFabric来保持服务始终正常运行。这样,无论何时回收,AppFabric都会自动为您的服务热身。只需确保在实例化服务时构建缓存,而不是在首次访问服务时构建缓存。
答案 3 :(得分:0)
您可以使用IIS7应用程序预热模块
答案 4 :(得分:0)
您可以使用的一个选项是将缓存移出WCF服务并转移到专用缓存服务,例如Memcached或使用Microsoft AppFabric Caching
这允许您将缓存数据的存储与WCF服务分开,这样您就可以更自由地在架构中管理和访问数据。