mvc5中ef6codefirst启动慢及间隙变慢的一些优化处理

杨帆 杨帆     2022-08-01     722

关键词:

问题描述:
第一次访问的时候很慢,后面再次打开页面很快,过了一段时间不访问页面然后再次打开页面又像第一次那样很慢。
采用的技术和环境:
使用技术: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:website1in,切换到程序的bin目录。
3、运行ngen命令
For 32 bit run:
%WINDIR%Microsoft.NETFrameworkv4.0.30319
gen install EntityFramework.SqlServer.dll

For 64 bit run:

%WINDIR%Microsoft.NETFramework64v4.0.30319
gen 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(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语句其实中只是在开发的时候有用,发布到生产环境,可以把这个给禁用了以提高性能。解决办法:

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

wpf虚拟化操作异常

根据这篇文章提供的方法会导致搜索变慢及有时候搜索不到 WPF中ItemsControl应用虚拟化时找到子元素的方法,具体可以修改为下面代码://Actionaction=()=>//{try{TreeViewItemitemSelected=null;//ForcetogenerateeverytreeViewitembyusingscrollitemif(virt... 查看详情

在 SQL Server 2017 中使用标识列间隙

...了原因,我想说的比较晚,这是频繁的服务器故障并重新启动并执行setidentitycache=off。希望这些大跳跃不会发生。现在我想在新条目的间隙中重用这些数字,最好的方法是什么?改变种子值是可能 查看详情

windowsserver2003变慢

...开事件查看器,发现系统出现大量的错误,DHCP服务没有启动,手动启动时出错。启动服务"winhttp。。。。服务时也出现错误"与WinHTTPWebProxyAuto-DiscoveryService服务相依的DHCPClient服务因下列错误而无法启动"。查看事件属性,系统提示... 查看详情

ef6codefirst

http://www.cnblogs.com/Bce-/p/3684643.html http://www.cnblogs.com/Gyoung/tag/Entity%20Framework/ http://www.cnblogs.com/easygame/category/564105.html http://www.360doc.com/userhome.aspx 查看详情

在 iPad 上运行的 iPhone 应用程序中横向视图顶部的 20 像素间隙

......当设备的方向更改为横向模式时,我有一个视图控制器启动并以编程方式加载WebView。这在iPhone中运行良好(横向视图顶部没有间 查看详情

关于windows系统不会变慢的设想

...件安装的过程,比如创建了哪些服务,哪些计划任务以及启动项等等。然后软件安装完成后把关于软件的进程,服务,计划任务等都删掉。然后手动创建一个脚本,用脚本代替软件的启动。比如,如果要启动sqlserver,我们可以写... 查看详情

为啥ie突然变慢?

...择“高级”选项卡,将“启用第三方浏览器扩展(需要重启动)”不选择,即去掉前面的勾,“确定”,重新启动计算机。 参考技术B宽带网速慢可能是由以下几个原因造成:1.病毒木马原因导致的,会导致导致网速慢。这种情... 查看详情

网络爬虫会随着时间变慢

...于在facebook中搜索诸如好友列表之类的公共信息。该程序启动得相当快,但一天后运行它变得越来越慢,我不知道为什么?谁能告诉我为什么 查看详情

ef6codefirst,对已有数据库如何执行迁移

先执行:Enable-Migrations,会生成Migrations-》Configuration.cs再执行:Add-MigrationsInitialCreate–IgnoreChanges,会生成空************_InitialCreate.cs,忽略初始化再执行:Update-database-verbose,会更新__MigrationsHistory表这时修改e 查看详情

Visual C++ 函数突然变慢 170 毫秒(长 4 倍)

...需要65毫秒,但现在它突然显着增加。发生的情况是:我启动我的程序,并且在前30次左右的迭代中它按预期执行,然 查看详情

为啥 xcode 中 uiviewcontroller 的顶部有间隙?

】为啥xcode中uiviewcontroller的顶部有间隙?【英文标题】:whygaptopofuiviewcontrollerinxcode?为什么xcode中uiviewcontroller的顶部有间隙?【发布时间】:2015-08-2407:25:17【问题描述】:我无法说服为什么UIViewController的顶部有一个间隙?我已经... 查看详情

如何管理自动布局中两个视图之间的间隙

】如何管理自动布局中两个视图之间的间隙【英文标题】:Howtomanagethegapbetweentwoviewsinautolayout【发布时间】:2015-07-1008:31:43【问题描述】:我正在为我的ViewController使用自动布局我知道如何以编程方式使用约束来定义两个视图之... 查看详情

MVC5 中 ActionLink 的 HTML 按钮

】MVC5中ActionLink的HTML按钮【英文标题】:HTMLbuttonfromActionLinkinMVC5【发布时间】:2021-12-2616:26:15【问题描述】:我有这样的ActionLink:<tdclass="options">@Html.ActionLink("Settings","RedirectToSettings",newlocationId=item.LocationId)</td& 查看详情

当间隙设置为 0(响应式地图)时,为啥 CSS 网格中的图块之间存在小的像素间隙?

】当间隙设置为0(响应式地图)时,为啥CSS网格中的图块之间存在小的像素间隙?【英文标题】:WhyisthereasmallpixelgapbetweentilesinCSSgridwhengapissetto0(responsivemap)?当间隙设置为0(响应式地图)时,为什么CSS网格中的图块之间存在小的... 查看详情

在 MVC5 中添加视图

】在MVC5中添加视图【英文标题】:addviewinMVC5【发布时间】:2017-09-0701:46:04【问题描述】:当我在ASP.NETMVC5(visualstudio2015)中添加一个视图并将其加载到浏览器中时,它会显示:“/”应用程序中的服务器错误。找不到资源。描述:H... 查看详情

Pandas 时间序列:查找会话中的间隙,并使用单独的 ID 命名每个会话/间隙

】Pandas时间序列:查找会话中的间隙,并使用单独的ID命名每个会话/间隙【英文标题】:PandasTimeseries:findgapsinsessions,andnameeachsession/gapwithseparateID【发布时间】:2021-09-0716:09:37【问题描述】:我正在为一个明显简单的任务而苦苦挣... 查看详情

MVC5 - 如何在 DropDownListFor Html 助手中设置“selectedValue”

】MVC5-如何在DropDownListForHtml助手中设置“selectedValue”【英文标题】:MVC5-Howtoset"selectedValue"inDropDownListForHtmlhelper【发布时间】:2017-06-0219:46:42【问题描述】:正如问题所说:如何在DropDownListForHtmlhelper中设置selectedValue?尝... 查看详情

在电话间隙中使用本地存储

】在电话间隙中使用本地存储【英文标题】:UsingLocalstorageinphonegap【发布时间】:2013-04-1210:19:33【问题描述】:我想为我的网络项目创建一个移动应用程序。我找到了phonegap。它说使用HTML、CSS和JavaScript轻松创建应用程序。我以... 查看详情