MVC5中EF6 Code First启动慢及间隙变慢优化的实践经验(转)
我使用MiniProfiler.EF来监控来诊断到底是什么导致页面第一次访问为什么这么慢。监控到的结果如下图:
再次访问结果:
隔很久不访问再次访问页面响应时间也能保持4-8秒内。
第一、问题原因分析
MVC的程序第一次访问比较慢的的问题由于第一次是要处理视图文件.cshtml(生成为.cs文件)、加载引用的dll程序文件和初始化程序池等等。
第二、优化方案
一、安装Application Initialization
这是在iis8出来后才有的,iis8内置的功能,而对于iis7.5也提供了一个扩展以支持这个功能。
Application Initialization Module for IIS 7.5
在页面接近底部的地方,找到适合自己架构的安装链接
- x86 for Windows 7
- x64 for Windows 7 or Windows Server 2008 R2
安装这个iis模块后,在iis界面中并没有模块图标和配置界面,还需要安装:
http://pan.baidu.com/s/1c091WxM
安装成功之后会多了一个配置如下图:
如果仅配置程序池StartMode为AlwaysRunning还不放心的话,
也可以同时针对站点开启preload和DoAppInitAfterRestart。
设置应用程序池如下图:
设置网站如下图
配置好后,测试了下,效果十分不错。
回收程序池后首次打开各站点,延迟都很低。
其实这个模块的思路和定时从外部触发一个访问是一样的,只是,更好的地方在于,它本身在程序池回收重启的时候就完成了这件事,而不会让外部访问有机会遇到首次访问的情况。
二、用Ngen安装生成EF的本地镜像
For 64 bit run:
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install EntityFramework.SqlServer.dll
三、禁用第一次ef查询对表__MigrationHistory的问题
使用了ef的Code first会在第一次ef查询的时候会对__MigrationHistory访问,是为了检查数据库和model是否匹配,以保证ef能正常运行。通过监测会先执行下面的sql:
- SELECT
- [GroupBy1].[A1] AS [C1]
- FROM ( SELECT
- COUNT(1) AS [A1]
- FROM [dbo].[__MigrationHistory] AS [Extent1]
- ) AS [GroupBy1]
- GO
- SELECT TOP (1)
- [Extent1].[Id] AS [Id],
- [Extent1].[ModelHash] AS [ModelHash]
- FROM [dbo].[EdmMetadata] AS [Extent1]
- ORDER BY [Extent1].[Id] DESC
- GO
这段sql语句其实中只是在开发的时候有用,发布到生产环境,可以把这个给禁用了以提高性能。解决办法:
- Database.SetInitializer<lanhuBlog.DAL.BlogContext>(null);
lanhuBlog.DAL.BlogContext这是我项目的EF上下方类,你要根据你的项目替换成自己的EF上下方类。
四、Model和DAl单独的分层的
五、EF Pre-Generated Mapping Views(预生成映射视图)
- using (var dbcontext = new EFDbContext())
- {
- var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext;
- var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
- mappingCollection.GenerateViews(new List<EdmSchemaError>());
- //对程序中定义的所有DbContext逐一进行这个操作
- }
六、补充
如果你觉得这还没有解决”过了一段时间不访问页面然后再次打开页面变慢“的问题,而且不能忍受第一次访问还是有点慢,可以设置应用程序池的”闲时超时“和回收”固定时间间隔“长一些或者建一个计划任务定时去访问使用了ef的页面,这样给ef热身,让ef不变冷,这样可以防止长时间不请求网站,应用程序进程停止再次访问变慢的问题。设置应用程序池的时间如下图:
闲时超时默认是20分钟,如果在超过20分钟都没有请求这个应用程序池工作进程就要关闭。这里你可以设置根据自己需要设置长一些。
最新文章
- elasticsearch运维实战之2 - 系统性能调优
- 主流的单元测试工具之-JAVA新特性-Annotation 写作者:组长 梁伟龙
- CSS3制作各种形状图像
- BZOJ2597 [Wc2007]剪刀石头布(最小费用最大流)
- css知识点积累
- Logcat 不显示日志的另一个原因. 跟cocos2dx关系不大.
- CSS3--实现特殊阴影 (实例)
- POJ_3579_Median_(二分,查找第k大的值)
- 命令行运行android模拟器
- Linux UGO和ACL权限管理
- 启动tomcat后struts框架报异常严重: Exception starting filter struts2 Unable to load configuration. - Class: java.net.PlainSocketImpl
- Redis 与 Memcache
- 【又长见识了】C#异常处理,try、catch、finally、throw
- 网站开发进阶(二十四)HTML颜色代码表
- ASP.NET Core Web API 版本控制
- 与PON相关的abbreviation
- 一次scrapy失败的提示信息:由于连接方在一段时间后没有正确答复或连接的主机没有反 应,连接尝试失败
- oracle 基本信息
- [javascript]—jQuery解析本地 XML 文档
- 提交json串格式的POST请求
热门文章
- 【Java EE 学习 47】【Hibernate学习第四天】【sesion】【一级缓存】【懒加载】
- 【Java EE 学习 35 上】【strus2】【类型转换器】【struts2和Servlet API解耦】【国际化问题】【资源文件乱码问题已经解决】
- AngularJS中bootstrap启动
- RSA的傻瓜原理
- MVC 好记星不如烂笔头之 --->; 全局异常捕获以及ACTION捕获
- UWP webview 键盘bug,回退页面,键盘会弹一下。
- JavaScript Bind()趣味解答 包懂~~
- css样式思维导图
- C# 先说IEnumerable,我们每天用的foreach你真的懂它吗?
- enumerate()