问题描述:
第一次访问的时候很慢,后面再次打开页面很快,过了一段时间不访问页面然后再次打开页面又像第一次那样很慢。
采用的技术和环境:
使用技术:EF6+MVC5
服务器环境:Windows 2012,Windows 2008 都是64位 + IIS7.5
 

第一、问题原因分析

EF方面的原因:
1、Code First第一次启动会对比程序中的Model与数据库表(database initializer ),生成Model与数据库的映射视图
2、随着EF的开源,EF从6开始就不会包含在.net Framework中,安装.net Framework默认是不会安装EF的。因此EF程序集就没有生成本地镜像,这样每次程序启动,EF的代码都会通过just-in-time (JIT) compiler(即时编译器)把MSIL中间代码编译成本机能识别的本地代码。因为这个生成的本地代码存在程序运行的进程里面的内存中,它将回收当程序进程被终止(例如:iis程序池回收,程序池默认是按需触发运行的,没人访问它就不启动了)。由于EF框架还是比较大的,EF6文件大小到4-5M了,所以每次启动都要重写编译本地代码有比较明显的性能影响。
 
抛开EF框架程序启动慢的问题主要有以下两方面的原因:
1、站点更新后重新加载程序文件;
2、iis程序池回收后也会需要重新加载(程序池默认是按需触发运行的,没人访问它就不启动了)

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界面中并没有模块图标和配置界面,还需要安装:

https://yunpan.cn/OcMvrRKi3a8Wbu  访问密码 ce02

安装成功之后会多了一个配置如下图:

如果仅配置程序池StartMode为AlwaysRunning还不放心的话,
也可以同时针对站点开启preload和DoAppInitAfterRestart。

设置应用程序池如下图:

设置网站如下图

配置好后,测试了下,效果十分不错。
回收程序池后首次打开各站点,延迟都很低。
其实这个模块的思路和定时从外部触发一个访问是一样的,只是,更好的地方在于,它本身在程序池回收重启的时候就完成了这件事,而不会让外部访问有机会遇到首次访问的情况。

二、用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的本地镜像。

三、禁用第一次ef查询对表__MigrationHistory的问题

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

SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT() AS [A1]
FROM [dbo].[__MigrationHistory] AS [Extent1]
) AS [GroupBy1]
GO
SELECT TOP ()
[Extent1].[Id] AS [Id],
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC
GO

这段sql语句其实中只是在开发的时候有用,发布到生产环境,可以把这个给禁用了以提高性能。解决办法:

Application_Start加代码
Database.SetInitializer<Magicodes.WeiChat.Data.AppDbContext>(null);
Magicodes.WeiChat.Data.AppDbContext这是我项目的EF上下方类,你要根据你的项目替换成自己的EF上下方类。 

四、Model和DAl单独的分层的

为了减少model和DAL导致重新编译dll带来的性能影响。把Model和DAL都单独的分层,编译成单独的dll。 

五、EF Pre-Generated Mapping Views(预生成映射视图)

Application_Start加入下面代码:
using (var dbcontext = newAppDbContext()) 
{
var objectContext = ((IObjectContextAdapter)dbcontext).ObjectContext;
var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
mappingCollection.GenerateViews(new List<EdmSchemaError>()); //对程序中定义的所有DbContext逐一进行这个操作
}

六、补充

如果你觉得这还没有解决”过了一段时间不访问页面然后再次打开页面变慢“的问题,而且不能忍受第一次访问还是有点慢,可以设置应用程序池的”闲时超时“和回收”固定时间间隔“长一些或者建一个计划任务定时去访问使用了EF的页面,这样给ef热身,让EF不变冷,这样可以防止长时间不请求网站,应用程序进程停止再次访问变慢的问题。设置应用程序池的时间如下图:

闲时超时默认是20分钟,如果在超过20分钟都没有请求这个应用程序池工作进程就要关闭。这里你可以设置根据自己需要设置长一些。

备注:以上内容参考了http://www.lanhusoft.com

MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理的更多相关文章

  1. MVC5中EF6 Code First启动慢及间隙变慢优化的实践经验(转)

    最近项目在使用EF了,mvc使用EF确实方便,因为添加功能的时候可以使用vs自动生成用ef的增.删.查.改的模板,大的提高的工作效率.但是很多人都遇到过用EF开发的程序在第一次访问的时候会比用ADO纯 ...

  2. MVC5与EF6 Code First 第一个入门完整实例教程

    mvc如今火的不行,我今天就来介绍一个MVC5与EF6开发的实际的入门实例,因为EF6默认是Code First的,所以我今天也就用EF6 的Code First来做一个简单的实例,为了让实例显得简单 ...

  3. MVC5使用EF6 Code First--创建EF数据模型(一)

    此Web应用程序演示如何使用Entity Framework 6和Visual Studio 2015创建ASP.NET MVC 5应用程序.本教程使用“Code First ”即代码先行.有关如何在 ...

  4. MiniProfiler(MiniProfiler.EF6监控调试MVC5和EF6的性能)

    git:  https://github.com/MiniProfiler 以前开发Webform的时候可以开启trace来跟踪页面事件,这对于诊断程序的性能是有很大的帮助的,起到事半功倍的作用,今天 ...

  5. MiniProfiler.EF6监控调试MVC5和EF6的性能

    转自:蓝狐学MVC教程 以前开发Webform的时候可以开启trace来跟踪页面事件,这对于诊断程序的性能是有很大的帮助的,起到事半功倍的作用,今天我就来谈用mvc开 发项目的调试和性能监控.EF框架 ...

  6. MVC5中Model层开发数据注解 EF Code First Migrations数据库迁移 C# 常用对象的的修饰符 C# 静态构造函数 MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上) MVC 的HTTP请求

    MVC5中Model层开发数据注解   ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证( ...

  7. 用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的Code First迁移和部署

    用 MVC 5 的 EF6 Code First 入门 系列:MVC程序中实体框架的Code First迁移和部署 这是微软官方SignalR 2.0教程Getting Started with En ...

  8. ASP.NET MVC5 与EF6学习系列

    最近学习使用MVC5和EF6,博客园搜索了一番,写下这篇文章记录,以便学习使用. 一.ASP.NET MVC5 网站开发 @洞庭夕照写的博客系列 ASP.NET MVC5 网站开发实践 - 概述 AS ...

  9. MvcMovieStore mvc5.0,EF6.01

    MVC 5 实例教程(MvcMovieStore 新概念版:mvc5.0,EF6.01) - 4.创建数据上下文和数据实体模型 说明:MvcMovieStore项目已经发布上线,想了解最新版本功能请登 ...

随机推荐

  1. PHP插入法排序

    /** 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法. 它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描, 找到相应位置并插入.插入排序在实现上 ...

  2. Android 中通过切割图片创建人物行走动画

    以前一直使用序列图片来实现动画效果,造成空间的极大浪费,所以想要尝试下切割图片来实现动画. 如图所示,是由66rpg纸娃娃系统生成的角色行走图.本程序必须实现将人物的整体图片切割后存入4x4的数组来动 ...

  3. 由浅到深理解ROS(4)

    消息和消息类型 节点能相互传递消息,节点之间通信也是基于消息.消息类型也就是数据类型数据类型,理解消息的类型很重要,因为它决定了消息的内容.也就是说,一个话题的消息类型能告诉你该话题中每个消息携带了哪 ...

  4. iOS开发---业务逻辑

    iOS开发---业务逻辑   1. 业务逻辑 iOS的app开发的最终目的是要让用户使用, 用户使用app完成自己的事就是业务逻辑, 业务逻辑的是最显眼开发工作.但是业务逻辑对于开发任务来说, 只是露 ...

  5. 【BZOJ1492】[NOI2007]货币兑换Cash 斜率优化+cdq分治

    [BZOJ10492][NOI2007]货币兑换Cash Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下简称B券).每 ...

  6. Cocos2d-x 3.1 环境搭建和创建project

    Cocos2d-x 3.x改版了非常多,之前搭过一次环境,可是没截图.这次趁着重装电脑,一边搭建一边截图.此博文仅仅是为了记录而不是为了教学,所以很多其它讲的是搭建过程.本文基本上參考这篇博客:htt ...

  7. Nodejs课堂笔记-第四课 Dynamodb为何物

    本文由Vikings(http://www.cnblogs.com/vikings-blog/) 原创,转载请标明.谢谢! 我喜欢带着目标来学习新知识.因此学习nodejs过程中,不喜欢只看枯燥的语法 ...

  8. C#自己写的第一个小程序,庆祝一下

    Packages.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; na ...

  9. python基础4 ----字符编码

    python基础---字符编码 一.了解字符编码 1. 文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容 ...

  10. HDU - 1800 Flying to the Mars 【贪心】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1800 题意 给出N个人的 level 然后 高的level 的 人 是可以携带 比他低level 的人 ...