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的本地镜像
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的本地镜像。
%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 具体看文档