IIS 解决首次加载慢的问题 以及EF预热 并且IIS cache内存丢失处理

之前遇到一个问题 cache过几秒自动删除 回调函数也看了

DateTime now = DateTime.Now;
            string cachedString = (string)HttpContext.Cache["Now"];
            if (string.IsNullOrEmpty(cachedString))
            {
                cachedString = now.ToString();
                HttpContext.Cache.Insert("Now", now.ToString(), null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration,
                      System.Web.Caching.CacheItemPriority.NotRemovable,
                     new System.Web.Caching.CacheItemRemovedCallback(OnMoveCacheBack)//移除时调用的回调函数
                );
            }

   private void OnMoveCacheBack(string key, object value, CacheItemRemovedReason reason)
        {
            DateTime now = DateTime.Now;
            string cachedString = (string)HttpContext.Cache[key];
            if (!string.IsNullOrEmpty(cachedString))
            {
                HttpContext.Cache.Remove(key);
            }
            HttpContext.Cache.Insert("Now", now.ToString(), null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration,
                   System.Web.Caching.CacheItemPriority.NotRemovable,
                  new System.Web.Caching.CacheItemRemovedCallback(OnMoveCacheBack)//移除时调用的回调函数
             );
        }
回调函数

解决方案  (主要是虚拟内存和专用内存 设为0   因为服务器内存高了 会自动删)

 

 然后就是闲置超时 默认20分钟过期

 

 

1.编辑网站对应应用程序池启动模式

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

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

 

 2.开启对应网站预加载

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

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

 

3.编辑网站对应应用程序池闲置超时

在网站空闲,即没有请求的时间达到设置值(默认20分钟),应用程序池会发生回收,比如session 会被清空。,应用程序池会发生回收

操作路径:应用程序池 -> 网站对应程序池 -> 右键,高级设置 ->选择,闲置超时设为0 默认 20分钟

4.(在应用程序池的运行时间达到设置的间隔,应用程序池会发生回收,比如session 会被清空;)

 这个是默认的间隔 41760分钟 

当然你不回收设置为 True 和 0分钟

5.EF预热

为什么Entity Framework的初始化速度慢如蜗牛呢?

对于在应用程序中定义的每个DbContext类型,在首次使用时,Entity Framework都会根据数据库中的信息在内存生成一个映射视图(mapping views),而这个操作非常耗时。

在第1次调用DbContext进行数据库操作时会进行缓慢的mapping views生成操作,后续的DbContext操作会共享已经生成的mapping views,不受这个问题影响。但是要注意的是你定义的每一个DbContext都会面临这个问题。

而我们的缓解之道则是在应用程序初始化时一次性触发所有的DbContext进行mapping views的生成操作——调用StorageMappingItemCollection的GenerateViews()方法。

5.1预生成映射视图

将代码放在Application_Start中调用PreApplicationStartMethod中执行

private void PreApplicationStartMethod()
        {
            using (var dbcontext = new XXXDBContext())
            {
                var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext;
                var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List<EdmSchemaError>());
            }  //对程序中定义的所有DbContext逐一进行这个操作
        }

5.2 禁用第一次ef查询对表__MigrationHistory的问题(仅codefirst)

使用了ef的Code first会在第一次ef查询的时候会对__MigrationHistory访问,是为了检查数据库和model是否匹配,以保证ef能正常运行。

解决办法:Application_Start加代码

protected void Application_Start()
        { 
             //.......
            RouteConfig.RegisterRoutes(RouteTable.Routes);
             
#if DEBUG
            BundleTable.EnableOptimizations = false;//关闭文件压缩功能
#else
            BundleTable.EnableOptimizations = true;//开启文件压缩功能
            Database.SetInitializer<MMISDBContext>(null);
#endif
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            PreApplicationStartMethod();
        }

MMISDBContext这是我项目的EF上下方类,你要根据你的项目替换成自己的EF上下方类。

5.3 用Ngen安装生成EF的本地镜像

1、打开cmd窗口
2、定位到dll所在的目录,如:cd d:\website1\bin,切换到程序的bin目录。
3、运行ngen命令
For 32 bit run:
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install EntityFramework.SqlServer.dll
For 64 bit run:
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install EntityFramework.SqlServer.dll

注意:这里根据你自己机器(是32还是64)和.net版本,选择相应的命令,只需要安装EntityFramework.SqlServer.dll,因为安依赖EntityFramework.dll,会自动安装生成EntityFramework.dll的本地镜像。

 4.查看是否在本机映像缓存中,也列出了依赖子的相关类库
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen display EntityFramework

文档:https://docs.microsoft.com/zh-cn/dotnet/framework/tools/ngen-exe-native-image-generator

卸载是uninstall  具体看文档

posted @ 2020-12-31 13:31  netlock  阅读(796)  评论(0编辑  收藏  举报