让多个请求等待第一个请求完成(缓存)

时间:2015-09-25 08:41:35

标签: c# asp.net caching

我有一个web api,它有一些get方法,可以将一些分布式查询提升到运行时间很长且cpu很贵的多个系统。 所以我们添加了output caching。像魅力一样工作,在处理完第一个查询后,它非常快。

所以现在我发布了一个(可能是常见的?)问题。 想象一下缓存失效或过期的情况(出于某些原因),而不是一个客户端一次调用web api而是100个客户端。目前发生的是100个客户端开始运行长时间运行的查询,并且cpu爆炸到100%,服务器实例崩溃并且不再响应。我基本上想要的是,只有第一个请求执行处理并让所有其他请求等到他完成查询并将结果添加到缓存。然后所有其他人都可以从缓存中获得响应。

我知道有大约1000种方法可以实现它,但我想知道是否有一般模式或最佳实践?或者我必须实施锁?或者使用TPL或者什么?坦率地说,我不知道从哪里开始?

非常感谢你。

编辑 除了下面非常好的答案,我还发现了这篇文章: http://www.asp.net/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/queue-centric-work-pattern

1 个答案:

答案 0 :(得分:5)

所需方式正在使用消息队列或服务总线。将您的任务排入队列并在构建缓存时停止将它们出列。

这更容易处理,因为它只是暂停后台服务(例如,,您可以从Windows服务实现消息队列/服务总线处理 - 您可能需要查看{{3}为此 - )并恢复它。

您的API应该排队任务而不是直接处理它们。

可能的消息队列:

在你的情况下,我会采用MSMQ方式,因为这是一个简单的场景,你只想将消息入队/出列...

如果我在与Web API相同的过程中需要它...

  

Matias非常感谢你的回答和好的建议。什么   如果我被迫采用进程方式,你会建议吗?   它与web api托管的过程相同吗?

一个简单的解决方案可能是使用ConcurrentQueue<T>模拟一个不可靠的排队系统,并创建一个任务处理器线程,这可能会在重建缓存时暂停或恢复。

如果你在IIS上托管你的WebAPI,我会转而在一个名为 self-host 的进程中托管它。了解此阅读NServiceBus