zoukankan      html  css  js  c++  java
  • 处理EF第一次加载过慢问题

    本文转载自:https://www.cnblogs.com/sunShineJing/p/5083184.html

    创建mvc web application,采用code first 的方式,MVC5,EF6.0 整了一个网站。开发完之后。直接publish。就这样部署到服务器上了。

    在使用过程中发现,网站打开的速度有点慢。而且每隔一段时间不使用,网站的打开速度就变慢。

    问题分析:

    一开始首先想到的是IIS的应用程序池释放的问题。

    后来配置了iis还是过一段时间访问变慢。

    后来为了快速解决这个问题,只能先做了一个bat文件,在服务器端模拟一段时间内访问这个网站一下。这样用户在访问的时候不会体会到网站的访问速度变慢的问题。

    1
    2
    3
    4
    5
    6
    @echo  正在关掉所有的IE进程(需要设置默认浏览器是IE)
    taskkill   /im iexplore.exe /f /t
    @echo 正在通过ping来延迟80秒钟,以方便IE打开页面
    ping 127.0.0.1 -n 10
    @echo 正在访问 http://localhost
    start "C:\Program Files\Internet Explorer\iexplore.exe"  http://localhost

     这样隔一段时间变慢的问题已经解决了,但是还没有查找到这是什么原因。

    后来看到一篇文章说 是因为EF 的原因。

    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了,所以每次启动都要重写编译本地代码有比较明显的性能影响。
     

    第二、优化方案

    我主要是通过以下几方面来优化

    一、安装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的本地镜像

    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:

    1. SELECT
    2. [GroupBy1].[A1] AS [C1]
    3. FROM ( SELECT
    4. COUNT(1) AS [A1]
    5. FROM [dbo].[__MigrationHistory] AS [Extent1]
    6. ) AS [GroupBy1]
    7. GO
    8. SELECT TOP (1)
    9. [Extent1].[Id] AS [Id],
    10. [Extent1].[ModelHash] AS [ModelHash]
    11. FROM [dbo].[EdmMetadata] AS [Extent1]
    12. ORDER BY [Extent1].[Id] DESC
    13. GO

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

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

    四、Model和DAl单独的分层的

    用vs建一个mvc项目,Model、DAL、Controller、View都在Web项目里面。为了减少model和DAL导致重新编译dll带来的性能影响。我把Model和DAL都单独的分层,编译成单独的dll了。
     

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

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

    六、补充

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

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

  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/quangeshishen/p/8275388.html
Copyright © 2011-2022 走看看