IIS为低流量网站提供了一个烦人的功能,它可以回收未使用的工作进程,导致第一个用户在一段时间后到达网站,以获得极长的延迟(30秒以上)。
我一直在寻找问题的解决方案,我找到了这些潜在的解决方案。
一个。 Use the Application Initialization plugin
B中。 Use Auto-Start with .NET 4
℃。 Disable the idle-timeout (under IIS Reset)
我想知道哪一个更受欢迎,更重要的是,为什么有这么多解决方案来解决同样的问题? (我的猜测是他们不是,我只是没有正确理解的东西)。
修改
执行 C 似乎足以让我的网站保持热身,但我发现我网站的真正根源是与Entity Framework有关,我似乎无法做到这一点弄清楚为什么它会变冷。请参阅this问题,其中尚未得到解答已被回答!
我最终只是偶尔打warm up script点击我的网站,以确保它保持快速。
答案 0 :(得分:33)
选项A,B和D似乎属于同一类别,因为它们只影响初始开始时间,它们会对网站进行预热,例如在内存中编译和加载库。
使用C,设置空闲超时应该足够快,以便快速提供对服务器的后续请求(重新启动应用程序池需要相当长的时间 - 大约几秒钟。)
据我所知,超时存在是为了节省内存在该机器上并行运行的其他网站可能需要的内存。价格是一次缓慢加载的时间。
除了在用户不活动时应用程序池关闭的事实,应用程序池也会默认每1740分钟(29小时)回收一次。
来自technet:
Internet信息服务(IIS)应用程序池可以 定期回收以避免可能导致的不稳定状态 应用程序崩溃,挂起或内存泄漏。
只要保留应用程序池回收,就足够了。 但是,如果您真的想要大多数组件的顶级性能,您还应该使用类似您提到的应用程序初始化模块。
答案 1 :(得分:8)
虚拟主机挑战
您必须记住,如果您像许多我们(较小的公司和个人)一样托管在共享服务器上,则没有任何机器配置选项可用。
ASP.NET MVC开销
我的网站在超过20分钟内没有被点击(并且网络应用已停止)时至少需要30秒。这很糟糕。
测试效果的另一种方法
还有另一种方法来测试它是否是你的ASP.NET MVC启动或其他东西。在您的网站上放置一个普通的HTML页面,您可以直接点击它
如果问题与ASP.NET MVC启动有关,那么即使Web应用程序尚未启动,HTML页面也会立即呈现。
这就是我第一次认识到问题出在ASP.NET MVC创业公司的方式。
我随时都加载了一个HTML页面,它会加载速度非常快。然后,在点击该HTML页面后,我点击了我的一个ASP.NET MVC URL,并且我收到了Chrome消息" Waiting for raddev.us ..."
使用有用脚本进行的另一项测试
之后我编写了一个LINQPad(请查看http://linqpad.net以获取更多信息)脚本,该脚本每隔8分钟就会到达我的网站(少于应用程序卸载的时间 - 应该是20分钟)而我让它运行几个小时。
当脚本运行时,我点击了我的网站,每次我的网站都快速出现。这给了我一个好主意,很可能我遇到的缓慢是因为ASP.NET MVC的启动时间。
获取LinqPad,您可以运行以下脚本 - 只需将URL更改为您自己的URL并让它运行即可轻松测试。 祝你好运。
注意:在LinqPad中,您需要按 F4 并添加对System.Net的引用,以添加将检索您的页面的库。
ALSO :确保更改String URL变量以指向将从ASP.NET MVC站点加载路由的URL,以便引擎运行。
System.Timers.Timer webKeepAlive = new System.Timers.Timer();
Int64 counter = 0;
void Main()
{
webKeepAlive.Interval = 5000;
webKeepAlive.Elapsed += WebKeepAlive_Elapsed;
webKeepAlive.Start();
}
private void WebKeepAlive_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
webKeepAlive.Stop();
try
{
// ONLY the first time it retrieves the content it will print the string
String finalHtml = GetWebContent();
if (counter < 1)
{
Console.WriteLine(finalHtml);
}
counter++;
}
finally
{
webKeepAlive.Interval = 480000; // every 8 minutes
webKeepAlive.Start();
}
}
public String GetWebContent()
{
try
{
String URL = "http://YOURURL.COM";
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
Stream data = response.GetResponseStream();
string html = String.Empty;
using (StreamReader sr = new StreamReader(data))
{
html = sr.ReadToEnd();
}
Console.WriteLine (String.Format("{0} : success",DateTime.Now));
return html;
}
catch (Exception ex)
{
Console.WriteLine (String.Format("{0} -- GetWebContent() : {1}",DateTime.Now,ex.Message));
return "fail";
}
}
答案 2 :(得分:3)
写一个ping服务/脚本来打你的闲置网站是一个最好的方法,因为你将有一个完整的控制。如果您租用了专用的主机箱,则可以使用您提到的其他选项。
在共享主机空间中,预热脚本是最好的第一级防御(自助是最好的帮助)。这是一篇分享idea on how to do it from your own web application。
的文章答案 3 :(得分:2)
我使用 B ,因为与工作流程回收相结合意味着回收时只会有延迟。这避免了通常与初始化相关联的延迟以响应空闲之后的第一请求。您还可以保持回收利益。
答案 4 :(得分:2)
按计划ping网站的一个好方法是使用Microsoft Flow,每月最多750次“运行”。创建一个每小时点击您的网站以保持温暖的Flow是非常容易的。你甚至可以通过创建一个单独的流程来解决你的网站的多次点击。
答案 5 :(得分:1)
有关如何帮助解决性能问题的提示,请参阅此文章。这包括与启动相关的性能问题,在&#34;冷启动&#34;部分。无论您在本地或生产中使用何种类型的服务器,其中大部分都很重要。
如果应用程序从XML(包括Web服务...)反序列化任何内容,请确保对所有涉及deseriaization的二进制文件运行SGEN,并将生成的DLL放在全局程序集缓存(GAC)中。这预编译了运行SGEN的程序集所使用的所有序列化对象,并将它们缓存在生成的DLL中。这可以节省大量时间,从磁盘首次反序列化(加载)配置文件和初始调用Web服务。 http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx
如果任何IIS服务器没有对Internet的传出访问权限,请通过在machine.config中添加generatePublisherEvidence =“false”来关闭Authenticode二进制文件的证书吊销列表(CRL)检查。否则,每个工作进程在启动期间都会挂起超过20秒,同时它会超时尝试连接到Internet以获取CRL列表。 http://blogs.msdn.com/amolravande/archive/2008/07/20/startup-performance-disable-the-generatepublisherevidence-property.aspx
http://msdn.microsoft.com/en-us/library/bb629393.aspx
考虑在所有组件上使用NGEN。但是,如果不小心使用,这并不会带来很大的性能提升。这是因为必须在构建时仔细设置每个进程加载的所有二进制文件的基本加载地址,以使其不重叠。如果由于地址冲突而加载二进制文件时必须进行重新定位,那么使用NGEN几乎所有的性能提升都将丢失。 http://msdn.microsoft.com/en-us/magazine/cc163610.aspx
答案 6 :(得分:0)
在闲置4分钟后,我对第一个请求的响应持续出现了15秒的延迟。我的问题是我的应用程序对SQL Server使用Windows集成身份验证,并且服务配置文件位于与服务器不同的域中。在应用初始化时,这导致了从IIS到SQL的跨域身份验证-这是造成延迟的真正原因。我改为使用SQL登录而不是Windows身份验证。延迟立刻消失了。我仍然拥有所有应用程序初始化设置来帮助提高性能,但是就我而言,可能根本不需要它们。