IIS站点自预热

介绍

     众所周知ASP.NET第一次访问时需要JIT编译,这就导致了ASP.NET程序第一次访问速度特别慢,尤其是ASP.NET MVC Razor模板引擎是解释型的,第一次还会将它编译一次,从前我们经常会说第一个人访问的都是人品有问题的,但是应用程序池会每过20分钟(默认,可修改)自动回收一次,也就是说每20分钟就要做一次人品有问题的人。
    在IIS7.5之前我们想让我们只能设置的ASP.NET应用程序应用程序池的回收时间,比如设一个超大的时间,但是这样做只是防止了应用程序池定时回收,却不能解决重启后,或是其它原因进程回收后每一个人访问的慢的“人品问题”,所以微软在IIS7.5 WINDOWS 2008带的IIS上增加一个叫做热启动的功能。
    热启动的原理很简单,就是在IIS的配置文件中做一些设定并指定一个继承自System.Web.Hosting.IProcessHostPreloadClient的类,然后告诉IIS说,如果哪个应用程序池回收了再次激活启动的时候就执行一下这家伙,而这家伙的功能基本上就是初始化系统的数据。

配置方法

  1. 在站点项目中添加一个心跳检查的接口,接口不需要经过鉴权,以下是我添加方法:
  • 在Global.asax下的HttpApplication中添加
protected void Application_BeginRequest()
{
      var context = HttpContext.Current;
      if (context.Request.Path == "/health/ping")
      {
            context.Response.StatusCode = 200;
            context.Response.Write("OK");

            HttpContext.Current.ApplicationInstance.CompleteRequest();
      }
}
  1. 添加预热方法
  • 站点项目下添加如下类
public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient {
    public void Preload (string[] parameters) {
        try {
            Console.WriteLine($"{GetLocalIp()}预热中,开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
            //自动请求的url,其中http://localhost:8001 最好配置在config中,这边只是演示。
            string url = "http://localhost:8001/health/ping"; //请求地址
            HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
            req.Method = "GET";
            req.BeginGetResponse (o => {//一定要异步请求
                Console.WriteLine($"{GetLocalIp()}预热成功!结束时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
            }, null);
        } catch (Exception ex) {
            Console.WriteLine($"{GetLocalIp()}预热失败,失败原因:{ex.Message}");
        }
    }

    private string GetLocalIp () {
        ///获取本地的IP地址
        string addressIP = string.Empty;
        foreach (IPAddress address in Dns.GetHostEntry (Dns.GetHostName ()).AddressList) {
            if (address.AddressFamily.ToString () == "InterNetwork") {
                addressIP = address.ToString ();
            }
        }
        return addressIP;
    }
}
  1. 打开IIS站点下应用池的高级设置,如下图:
  • 把启动模式改成AlwayRunning
    image.png
  1. 选中根节点,在右边的功能中找到【配置编辑器】,如图所示:
    image.png
  2. 我们需要修改以下两个配置,如图所示
    image.png
  3. 打开serviceAutoStartProviders,添加预热类信息
    image.png
    image.png
  4. 打开sites配置,把预热与站点绑定
    image.png
    image.png
  5. 到此站点的热启动已经配置完毕,重新站点可以查看效果。

注意事项

  1. 在代码中最好将所有的都用try{}catch{}包住,因为如果这里抛出的异常会导致应用程序停止.
  2. 运行的状态我们可以从事件管理器中进行查看,或是自己在代码中写日志记录运行的状态.
  3. 这个类中所做的并不会引用站点的启动,不会执行应用程序的生命周期,也就是说不会调用Application_Start以及其它生命周期过程.所以在本例中我们会一个请求这个站点.
  4. 如果在这里请求站点时一定要用异步的方式Request.同步的Request会报超时.
posted @ 2020-07-18 21:29  小路哥  阅读(570)  评论(0)    收藏  举报