Eng*_*gin 5 vb.net asp.net multithreading webforms iis-8
TL; DR: 为性能做了重构,网站变慢了.在并发可视化器中,该图看起来像MSDN上描述的锁定车队.
我正在帮助重构ASP.NET网站以切换用户控件,使其无法在数据集上执行业务逻辑,从而在业务对象上执行表示逻辑,还可以减少用户控件的数据库调用.
我们已经注意到在引入涉及我们认为在多个领域中的性能改进的变化之后,性能显着下降(挂起/阻塞).
我们使用精益哨兵来监控我们网站的表现.根据挂起诊断,当GC运行时,线程池的线程用完(并根据诊断页面上的描述),它会阻止创建更多线程.根据内存诊断,GC Heap和Gen 0消耗大量内存(~9 GB).
我使用的内存分析器在Visual Studio中,并与我们的过度发现的问题DataAdapter和DataTable使用情况.内存消耗降至3 GB,但这仅对GC阻塞有帮助.它仍然比我们引入更改之前的速度慢,但我仍然看到由像CompilationLock.GetLock()和等函数引起的高负载阻塞BuildManager.GetBuildResultFromCacheInternal().谷歌搜索他们没有返回任何有用的东西.
这是一个使用JIT编译的网站.我认为问题CompilationLock可能是因为JIT编译并且想要运行预编译的网站,但是我们的一个全局Utilities类导致了一些Utilities我不知道的其他类/命名空间的歧义.我发现有一个Microsoft.Build.Utilities命名空间,但它没有在我们的网站中引用Microsoft.Build,当我自己引用时,我无法重现我自己环境中的歧义,所以我无法让网站在预分段模式上运行服务器来测试这个理论.
我使用Visual Studio的内存分配和检测分析器作为度量对内存分配和数据库调用量进行了额外的更改,但我没有注意到性能方面的任何进展.
我使用并发分析器来收集有关线程利用率的更多信息.我之前没有使用过这个工具,所以我不确定我的解释.每个句柄中有多个线程,在一个句柄中我看到42%的争用.我看到,当设置为"显示我的代码"时,DataAdapter.Fill和SqlHelper.ExecuteReader方法显示最多,并且WaitForSingleObjectExImplementation当它设置为"显示所有代码"时显示最多.
我遇到了一个关于ASP.NET网站性能问题的问题,并为每个页面设置EnableSessionState="ReadOnly"了,但我也没有注意到这个变化的区别.
并发可视化器和不良行为多线程应用程序的通用模式帮助我确定了问题.我的图表看起来不像是串行执行,但我看到了80-90%的同步,如Lock Convoys图所示.我也检查了关于锁定车队调试的SO问题.
我正在使用Screaming Frog来抓取网站,以便重现问题,并将Screaming Frog和Lean Sentry中的每秒请求数和响应时间作为性能指标.它可能不是最好的方式,但差异是明显的,可重复的,而且这几乎就是我所拥有的.
该网站最初大约10年前在VB.NET for .NET Framework 1.0中编码,并通过修复一些兼容性问题升级到.NET Framework 4.6.1.到目前为止,还没有任何架构变化.有共享的SqlHelper类,它是像共享数据存取功能的集合ExecuteDataset或ExecuteDatareader,即返回一个DataSet,DataReader或String值.这些函数读取的连接字符串信息web.config文件,并创建一个新的SqlConnection,SqlDataAdapter,SqlDataReader和SqlCommand对象来执行数据库操作.使用此共享类的数据访问层由每个模块(如购物车,类别,产品等)的类组成,这些类将在每个用户控件中实例化,并且它们由表示数据库中存储过程的函数组成.
我们在相关用户控件的页面加载内部或者在OnItemDataBound转发器的内部事件中引入了一些要实例化的新对象,并附加到其子用户控件的公共属性,这些属性被重构为使用该对象.但是,还有其他子用户控件需要多个数据表,因此我们决定将其中一个数据表存储在其中一个对象中,并通过将其分配给其公共属性将其传递给相关的用户控件.
我想我们通过引入这些对象来损害性能.即使数据库调用和内存消耗似乎减少了,我想知道对象是否导致线程一直被同步.
任何重构发生之前的图形:
我提到的所有重构应用后的图形:
你能帮我辨认一下这个问题吗?
你的问题比较复杂。我认为您有两个基本选择来解决重构性能问题:
\n\n将代码更改恢复到所有或大部分重构尚未完成且性能比当前体验更好的状态。然后,逐步添加新类以提高性能。如果更改不能提高性能,则撤消它并尝试其他方法。
将一些/大部分新添加的类替换为支持接口但缺乏性能开销的版本。有选择地执行此操作以隔离存在性能问题的位置。也许,该网站已经利用了一个未知的性能错误,该错误不是由添加的类的先前实现触发的。
我倾向于选项 1,尽管它可能会适得其反。这有点像美式足球中的双踢。当然,开车去球场真是太好了。但有时占主导地位的策略是弃踢,拿回球并尝试在另一次突破中得分。
\n| 归档时间: |
|
| 查看次数: |
165 次 |
| 最近记录: |