我有一个ASP.NET MVC 3 / .NET Web应用程序,它是严重数据驱动的,主要围绕“地点”(纽约,加利福尼亚等)的概念。
无论如何,我们有一些非常繁忙的数据库查询,它们在完成后会被缓存。
E.g:
public ICollection<Location> FindXForX(string x)
{
var result = _cache.Get(x.ToKey()) as Locaiton; // try cache
if (result == null) {
result = _repo.Get(x.ToKey()); // call db
_cache.Add(x.ToKey(), result); // add to cache
}
return result;
}
但我不想让不幸的第一个用户等待这个数据库调用。
数据库调用可能需要40-60秒,远远超过ASP.NET请求的默认超时。
我希望在我的应用启动时或之后不久,为某些“热门”地点(例如纽约,加利福尼亚州)“预热”这些电话。
我不想简单地在 Global asax (Application_Start)中执行此操作,因为应用启动时间太长。 (我计划在15个地点预先缓存,这样工作几分钟。)
有什么办法可以异步启动这个逻辑吗?也许旁边的服务是更好的选择?
我能想到的唯一其他选择是有一个管理页面,其中包含这些操作的按钮。因此,管理员(例如我)可以在应用启动后触发这些查询。这将是最简单的解决方案。
有什么建议吗?
答案 0 :(得分:6)
查看IIS 7.5的"Always running"应用设置。这基本上做的是在现有的应用程序池被回收时准备好应用程序池。当然,第一次需要40-60秒,但之后事情会很快,除非你重新启动机器。
答案 1 :(得分:5)
快速而肮脏的方式是从Task
点击Application_Start
但是我发现将这个功能包装到一些基础设施中是很好的,这样你就可以创建一个〜/ Admin / CacheInfo页面,让你监控可能在进程中的进度,状态和异常。加载缓存。
答案 2 :(得分:3)
在开始缓存变暖之前,我建议您首先查看它正在执行的逻辑读取次数,以检查查询是否“尽可能快”。
答案 3 :(得分:3)
听起来你应该将结果转储到一个单独的表中,并且有一个计划任务来定期重新填充该表。
如果一个预先计算的表格不够,因为它需要搜索的数据过多,那么您可以使用多个。
答案 4 :(得分:2)
一种解决方案是在Application_Start
方法中启动工作线程,在后台执行预热。如果你做得对,你的应用程序启动时间不会太长,因为线程将异步执行。
答案 5 :(得分:2)
一种选择是使用网站运行状况监控服务。它可用于检查网站运行状况,如果经常安排,则可以调用您的公共URL。
答案 6 :(得分:1)
正如斯科特所提到的那样,从Task
Application_Start
进行加载是可行的方法。
请注意 - 如果您的网站重新启动并且有10个人尝试查看加利福尼亚州,则您不希望最终同时尝试加载相同数据的10个_repo.Get(x.ToKey()); // call db
实例。
在应用程序状态中存储布尔值"IsPreloading"
可能是个好主意。在预加载功能开始时将其设置为true
,最后设置为false
。如果设置了该值,请确保您未在FindXForX
中加载任何15个预加载位置。
答案 7 :(得分:1)
建议您查看auto-starting您的应用,尤其是在负载均衡的情况下。