不可忽视的 .NET 应用5大性能问题

【编者按】本文系国内 ITOM 管理平台 OneAPM 翻译自 Steven Haines 的文章。Steven Haines 是 Pisksel 技术架构师,目前在奥兰多迪士尼乐园工做。他是在线教育网站 geekcap.com 的创始人,著有上百篇 Java 相关的文章以及三本 Java 著做:《Java 2 From Scratch》《Java 2 Primer Plus》以及《Pro Java EE Performance Management and Optimization》html

实现有效 APM 策略所面临的挑战:数据库

  • 代码依赖
  • 过分或没必要要的日志
  • 同步与锁
  • 潜在数据库问题
  • 潜在的基础架构问题

###一、代码依赖浏览器

开发程序是一项具备挑战性的工做。你不只要为了知足商业需求而创建程序逻辑,还要选择最合适的代码库和工具来帮助你。你能想象本身建立全部的日志管理代码,XML 和 JSON 解析逻辑,或全部的序列化库么?你固然能够编写代码来完成这些事,可是诸多开源开发者团队已经作好了这些事情,你又何须亲力亲为呢?此外,若是你正在与第三方系统集成,你会本身读完专有的通讯协议规范,仍是购买供应商提供的库帮你完成呢?缓存

我相信你会赞成:若是有人已经解决了你的问题,使用他的解决办法会比本身想办法解决效率更高。若是这是一个已经被许多公司采用的开源项目,那么极可能它已经通过完备的测试,文档充足,并且你应该找获得许多使用教程。服务器

然而,使用依赖库是有危险的。你须要回答如下问题:网络

  • 这个库真的写得很好而且已经充分测试了吗?
  • 你是否用与众多公司同样的方式使用这个库?
  • 你的使用方式是否正确?

请确保在选择外部库以前进行一些调查,若是你对某个库的性能有什么疑问,那就进行一些性能测试。开源项目很好的地方在于你能够访问它们的所有源代码以及测试套件和构建流程。下载它们的源代码,执行编译过程,并查看测试结果。若是你看到很高的测试覆盖率,那么就能够比没有测试案例时信心百倍!多线程

最后,确保正确地使用依赖库。若是正确使用,ORM 工具的确可以大大提升性能。ORM 工具的问题在于,若是你不花时间去学习如何正确地使用它,你就会轻易的砸本身脚,破坏本身的应用性能。关键就在于若是不花时间学习这些工具,本应帮助你的工具反而会伤害你。架构

###二、过分或没必要要的日志框架

日志记录是调试工具库里的强大武器,能够帮助你识别应用执行过程当中在特定时间内可能发生的异常。当错误发生时,捕捉错误信息并收集尽量多的上下文信息是很是重要的。然而,简洁地捕捉错误条件和过分记录之间是有差异的。工具

最广泛的两个问题就是:

  • 多级别异常日志
  • 错误配置生产日志级别

异常日志能帮助你了解应用程序中发生的问题,于是很是重要。但一个常见的问题是,应用程序全部层级的异常都进行记录。例如,你的某个数据访问对象捕获到一个数据库异常,并将该异常传达到服务层。服务层可能会捕捉该异常,并将其传达到网络层。若是咱们在数据层、服务层和网络层上都记录该异常,那么咱们对此相同的错误条件就有三条堆栈记录。这会致使写入日志文件的额外负担,还会使日志文件充满冗余信息。但这个问题很是广泛,我敢断言,若是你检查本身的日志文件,你极可能会发现多个这样的例子。

生产应用中常见的另外一个大的日志问题与日志级别有关。.NET 日志记录器定义了如下日志记录级别(.NET TraceLevel 与 log4net 中的命名会有所不一样,但绝对类似):

  • Off
  • Fatal
  • Error
  • Warning
  • Info
  • Verbose / Debug

在生产应用程序中,你应该只记录 error 或 fetal 级别的日志语句,在更宽松的环境中,捕捉 warning 甚至 info 级别的日志信息也彻底能够,可是一旦应用投入生产环境,用户负载将迅速填满日志并使应用程序陷入瘫痪。若是你不经意地将生产环境下的应用日志级别设为 debug,应用的响应时间比正常状况下高两或三倍都不奇怪!

三、同步与锁

有时候,你想确保应用代码中每次只有一个线程执行一段代码子集。 例如,读取单线程规则执行组件之类的共享软件资源,以及文件句柄或网络链接之类的共享基础架构资源。.NET 框架提供了许多不一样类型的同步策略,包括锁/监视器、进程间互斥,和读/写锁这类的专用锁。

无论你为何要同步代码或者选择什么机制实现代码同步,都会致使一个问题:那就是有部分代码一次只能由一个线程执行。 设想去超市,只有一个收银员在工做:许多人进入商店,浏览商品,将商品放进购物车里,但某一时候,他们不得不排队以进行支付。在这个例子中,购物是多线程的,每一个人都表明一个线程。然而结帐是单线程的,这意味着每一个人都要花费排队付款的时间。这个过程如图1所示。

不可忽视的 .NET 应用5大性能问题 图1:线程同步

咱们有七个线程,都须要访问一段同步代码块,因此它们依次得到权限访问该代码块,执行其功能,而后继续。

在图2中总结了线程同步的过程。 不可忽视的 .NET 应用5大性能问题

图2 线程同步过程

首先,为特定的对象(System.Object 派生)建立锁,意味着当一个线程试图进入同步代码块时必须获取该同步对象的锁。若是该锁可用,则该线程被授予执行同步代码的权限。在图2中的例子中,当第二个线程到达时,第一个线程已经占有了该锁,因此第二个线程被强制等待,直到第一个线程执行完毕。当第一个线程执行结束时,会释放该锁,而后第二个线程被授予访问权限。

正如你可能猜想到的,线程同步将给 .NET 应用带来一个极大的挑战。咱们设计应用程序时,但愿其能支持数十个甚至数百个同步请求,但线程同步会把全部处理这些请求的线程串行化,致使性能瓶颈!

解决的办法有两种:

  • 仔细检查同步的代码,以肯定是否存在其余可行办法
  • 限制同步代码块的范围

有时候,你要访问必须同步的共享资源,但不少时候,你能够用彻底避免同步的方法从新解决该问题。例如,咱们以前使用的规则过程引擎有单线程的要求,所以拖慢了程序中全部请求的执行速度。这显然是一个设计上的缺陷,咱们能够用一个能够并行工做的库取代之。你须要问本身是否有更好的选择:若是你在往一个本地文件系统写入信息,你是否能够把信息发送给某项服务,再由该服务将信息存储到数据库中?你是否能够将对象设为不可变,从而不管是否有多线程访问它都不要紧?等等,等等…

对于那些必需要同步的代码段,请合理地选择锁。你的目标是将同步代码块隔离以知足最低限度的同步要求。一般最好是定义一个特定的对象进行同步,而不是对包含同步代码的对象进行同步,由于你可能会在不经意间拖慢该对象的其余交互。最后,考虑使用读/写锁,而不是标准的锁,这样,你能够在资源只进行同步变化时,容许读操做。

###4.潜在的数据库问题

几乎全部的内容应用最终都会涉及到向/从数据库或文档存储储存/检索数据。所以,数据库、数据库查询,以及存储过程调优对应用程序的性能来讲是最重要的。

程序架构师/开发人员和数据库架构师/开发人员之间有一个哲学性的划分。应用程序架构师倾向于认为全部的业务逻辑都应该驻留在应用程序中,数据库应该只提供访问数据的通道。另外一方面,数据库架构师更倾向于认为将业务逻辑推到数据库中更有益提升性能。这个划分的答案极可能就是介于二者之间。

做为一个应用程序架构师,我倾向于将更多的业务逻辑应用在程序当中,但我彻底认可数据库架构师能更好的理解数据和与数据交互的最佳方式。我认为,这两个群体之间的协同合做才能产生最佳的解决方案。可是,无论你倾向于哪一方,请确保你的数据库架构师检查你的数据模型,全部的查询语句和存储过程,他们都有丰富的知识帮助你以最佳的方式来调整和配置数据库,他们有大量的工具能够为你调整查询语句。例如,有一些工具可用于 SQL 调优,遵循如下这些步骤:

  • 分析 SQL 语句
  • 肯定查询的执行计划
  • 利用人工智能生成备选的 SQL 语句
  • 肯定全部备选方案的执行计划
  • 提出最佳的查询方式来完成目标

当我在写数据库查询代码时,我使用了这类工具,并在高负载状况下量化告终果,一些细微的调整和优化,都能致使极大的性能提高。

###五、潜在的基础架构问题

以前提过,.NET 应用运行在分层的环境中,其层级结构如图3所示:

不可忽视的 .NET 应用5大性能问题 图3.NET分层执行模型

你的应用程序运行在 ASP.NET 或是 Windows Forms 容器中,使用 ADO 库与运行在 CLR 内部的数据库交互,而 CLR 运行在操做系统中,操做系统又运行在硬件里。而该硬件又与其余包含不一样技术堆栈的硬件经过网络相连。在你的应用与外部环境之间,以及在应用的组件之间,一般有多个负载平衡器。咱们还有 API 管理服务以及多级缓存。全部这一切,都是为了说明,基础构造数量庞杂,均可能影响应用程序的性能!

所以,你必须细致地调整基础架构。检查你的应用组件和数据库所运行的操做系统和硬件设备,以确保它们的最佳表现。测量服务器之间的网络延迟,并确保你有足够的带宽来知足应用程序之间的交互。检查缓存,确保较高的缓存命中率。分析负载平衡器的行为以确保请求很快地分发到全部可用的服务器。总之,你须要全面检查应用程序的性能,既包括应用业务交易也包括支持它们的基础架构。

OneAPM 助您轻松锁定 .NET 应用性能瓶颈,经过强大的 Trace 记录逐层分析,直至锁定行级问题代码。以用户角度展现系统响应速度,以地域和浏览器维度统计用户使用状况。想阅读更多技术文章,请访问 OneAPM 官方博客 本文转自 OneAPM 官方博客

相关文章
相关标签/搜索