IIS上解决ASP.Net第一次访问慢的处理

IIS中应用程序池和网站是单独存在的,但是网站运行必须建立在对应的应用程序池启动的前提下。

默认情况下,应用程序池在不活动情况下(无请求操作),一段时间后,将被IIS自动回收掉。
 

本篇经验中的方法能解决ASP.Net第一次访问慢,间隔一段时间后,又访问慢的问题。

安装IIS应用程序初始化功能,如下图所示:

应用程序开发->应用程序初始化

编辑网站对应应用程序池启动模式,操作路径:应用程序池 -> 网站对应程序池 -> 右键,高级设置 ->选择,启动模式 AlwaysRunning,如下图所示:

开启对应网站预加载,操作路径:网站 -> 对应网站 -> 右键,高级设置 ->选择,预加载已启用 True,如下图所示:

IIS上解决ASP.Net第一次访问慢的处理

设置配置编辑器,编写默认预加载请求,打开配置编辑器,如下图所示:

IIS上解决ASP.Net第一次访问慢的处理

在左上角配置节点选择system.webServer/applicationInitialization,其他配置如红圈中,如下图所示:

IIS上解决ASP.Net第一次访问慢的处理

在集合中添加一个初始化请求地址(用于IIS初始化默认请求地址),添加完成后,点击配置界面右侧的应用按钮,并重启应用程序池和网站,如下图所示:

IIS上解决ASP.Net第一次访问慢的处理

 

总结:

1、原理说明:IIS应用初始化会在网站第一次创建后或者对应网站的应用程序池回收后,自动开启新程序池,并启动网站初始化,模拟一次正常请求,使网站一直处于在线状态。

(此流程可以借助第三方工具或者服务模拟网站请求达到相同目的)

2、配置说明:

 (1)、启用应用程序池(AlwaysRunning):保证应用程序池在第一次创建或者被回收后,能自动再次重启运行。

 (2)、启用网站程序预加载(true):保证程序池在启动过后,网站能响应预加载动作。

 (3)、配置网站默认预加载路径:保证程序在程序池启动后,网站预加载过程中,能快速编译程序并进驻内存,保证请求快速响应。  

转载地址:https://jingyan.baidu.com/article/c843ea0bb6c13877931e4a2e.html

 

Asp.net Mvc站点部署在IIS上后,第一个用户第一次访问站点,都会比较慢,确切的说是访问站点的Action页面(即非静态页面,因为静态页面直接由IIS处理返回给用户即完成请求,而Action页面IIS要转交给Aspnet_Wp工作进程,进而涉及相关初始化操作,这些初始化操作是比较慢的。第二次访问站点就不需要再初始化了所以就快了)。

 这种第一次访问慢的问题不仅发生在网站第一次部署启动,也发生在站点重启站点程序池回收(经测试,第一次部署启动初始化所用时间会多一些,然后是站点重启,然后是站点回收)。

 

1.站点重启包含手动重启和修改web.config配置、修改IIS上站点配置、更新站点bin目录的dll等引起的自动重启。如果你的站点是新上线的web或者会持续修改添加功能的web,那难免会更新dll导致重启。其它编译型语言(比如java)也是如此,更新了服务端组件,都难免要重启站点。这边会分享.net环境下如何优化此问题;

2.站点程序池回收是IIS建议的,本来默认是29小时回收一次。为什么要建议回收呢,大致可以这样理解:一个每日定时回收的机制就像是在发生轻微内存泄露或者其它拖累Worker进程的因素的情况下,刷新IIS的良药,站点回收即节省了资源又提高了稳定性。然而,自动回收后第一次访问慢的问题困扰了许多人,其实只要稍微设置就可以解决,即没有困扰也拥有了回收的优点。

 

问题解决:

1.先在IIS上设置相应应用程序池的“高级设置”(IIS版本要在8或8以上,要知道IIS10早已出来了,如果你在用IIS很低的版本,然后在报怨IIS,我...),如下图,这样设置后,回收只会发生在凌晨04:00:00

 IIS上解决ASP.Net第一次访问慢的处理

要确定有安装IIS应用程序初始化功能,如下图

IIS上解决ASP.Net第一次访问慢的处理

 

2.在IIS上设置站点的“高级设置”,把【预加载已启用】设置为true。

设置完这两步,当站点(自动)回收时,访问站点也是秒开不受任何影响,它的原理是在回收时会保持站点持续运行,这样的回收可以理解为把旧的Worker内容平滑的移到新的Worker上,然后回收掉旧的Worker。但是要注意,回收会导致站点内存信息丢失,因此如果你的设计是把session放在内存,则就要设置永不自动回收,那只要在第1步的基础上把【特定时间】清空即可。不过我个人会建议你不要设计session放内存,你更新个dll导致站点重启,内存也是清空的,你不如把session放在memcache/redis中,如果你的系统还没用上这些,那你就用cookie代替session吧,cookie更灵活适用的场景也更多。

 

现在回收的问题完美解决了,接下来说说站点重启。站点重启肯定是要重新加载配置重新加载dll(不想重新加载dll的,看文章最后一段),初始化是免不了,默认重启后第一个用户第一次访问站点会触发初始化,那么我们可以在站点启动/重启时,系统自动发一个站点请求,让系统自己尝尝第一次访问慢的问题。

IIS站点启动时机自动请求站点

 1.启动站点时触发的时机

创建一个类,继承自IProcessHostPreloadClient接口,其Preload方法就是启动站点时触发。然后在里面自动访问站点,如下代码:

IIS上解决ASP.Net第一次访问慢的处理

   public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient
    {
        public void Preload(string[] parameters)
        {         
            try
            {
                //自动请求的url,其中http://localhost:8001 最好配置在config中,这边只是演示。
                string url = "http://localhost:8001/home2/about";
                using (var webClient = new WebClient())
                {
                    webClient.DownloadStringAsync(new Uri(url));//要异步请求
                }
            }
            catch (Exception e)
            {
                MvcApplication.DoLogToTxt("Preload Error:" + e.Message);
            }
        }
    }

IIS上解决ASP.Net第一次访问慢的处理

 

2. 修改IIS配置文件,让IIS能识别到刚写的ApplicationPreload类

打开IIS配置文件:%WINDIR%\System32\inetsrv\config\applicationHost.config 

IIS上解决ASP.Net第一次访问慢的处理

<applicationPools>
    <add name="MyAppWorkerProcess" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" /> <!-- 上面我们在IIS程序池界面中有设置过startMode项为AlwaysRunning-->
</applicationPools>

<!-- ... -->

<sites>
    <site name="MySite" id="1">
        <application path="/" serviceAutoStartEnabled="true" serviceAutoStartProvider="ApplicationPreload" />
    </site>
</sites>

<serviceAutoStartProviders>
    <add name="ApplicationPreload" type="WebApplication1.ApplicationPreload, WebApplication1" />
</serviceAutoStartProviders>

IIS上解决ASP.Net第一次访问慢的处理

最后一个条目的type,其中WebApplication1.ApplicationPreload是应用程序中实现IProcessHostPreloadClient接口的类的全名,WebApplication1是程序集名称。 

设置完这两步也就搞定了启动站点时自动访问站点。