zoukankan      html  css  js  c++  java
  • IIS+ASP.NET MVC必须知道的事

    来源:东汉

    cnblogs.com/michaeldonghan/p/9277302.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


    640?wx_fmt=png


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


    640?wx_fmt=png


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


    设置完这两步,当站点(自动)回收时,访问站点也是秒开不受任何影响,它的原理是在回收时会保持站点持续运行,这样的回收可以理解为把旧的Worker内容平滑的移到新的Worker上,然后回收掉旧的Worker。


    但是要注意,回收会导致站点内存信息丢失,因此如果你的设计是把session放在内存,则就要设置永不自动回收,那只要在第1步的基础上把【特定时间】清空即可。


    不过我个人会建议你不要设计session放内存,你更新个dll导致站点重启,内存也是清空的,你不如把session放在memcache/redis中,如果你的系统还没用上这些,那你就用cookie代替session吧,cookie更灵活适用的场景也更多。


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


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


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


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


    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);

             }

         }

    }


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


    打开IIS配置文件:%WINDIR%System32inetsrvconfigapplicationHost.config 


    <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>


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


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


    探讨


    在上面设置之前,我测试只更新站点部分dll,第一次访问需要1~4秒,测试的站点是含有CMS源码的站点,不算小了。


    之前有个面试官说他们公司站点更新一个dll,第一次访问需要10~30秒,甚至更久,这样正在访问站点的用户就要等待,然后一直在报怨IIS和.Net,想要投奔java的怀抱(这里不比较两种语言,它们各自有自己的优势),我问他是不是在Global.asax里Application_Start做了太多自己的初始化,要么有些初始化在用户访问到时处理负担分担出去,要么Application_Start异步处理初始化动作,但是他说这些自己的初始化都是用户访问前必须初始化好的。


    这应该是自己系统设计不够好不能怪.NET,如果是用了七七八八的第三方组件,比如EF初始化慢,那就换成轻量级的Dapper,然后好好学习一下《N种提升Asp.Net Mvc性能的方法》不要闭门造车。


    (你们更新一个站点的dll,第一次访问需要多少秒呢?)


    那么,在上面设置之后 ,如果更新站点dll后第一次访问需要1~4秒的情况下,系统自动帮你做了第一次访问,很可能正在访问的用户就不怎么察觉得出来站点有重启过。


    如果是高并发访问的大型网站,那就应该有负载均衡(IIS可以用NLB做负载均衡,或考虑CDN或DNS解析时就做负载均衡),应该有分布式等。


    最后 ,如果你的站点是因为更新dll而导致站点重启,而且对此问题深恶痛绝,那么可以用.NET的动态加载dll来解决,不是用AppDomain动态加载和卸载dll(这个太麻烦),而是用Assembly.LoadFile加载dll。


    比如Controller所在的dll是MvcA.dll,它引用了LibA.dll,当这两个dll都有修改时,如何让站点加载到这两个最新版本的dll。




  • 相关阅读:
    java.lang.NoSuchMethodError:antlr.collections.AST.getLine() I
    T7 java Web day01 标签HTML
    T6 s1 day19
    T5 s5 Day18
    T5 s4 Day 17
    T5 s3 day16
    T5 s2 Day 15
    T5 s1 day14
    T4 S03 day 12
    T4 S01 day1
  • 原文地址:https://www.cnblogs.com/hgmyz/p/12351764.html
Copyright © 2011-2022 走看看