编写高性能 Web 应用程序的10个技巧

web|程序|技巧|性能|技巧|性能

本文讨论:
常见的 ASP.NET 性能神话
有用的 ASP.NET 性能技巧和诀窍
在 ASP.NET 中处理数据库的一些建议
缓冲以及用 ASP.NET 进行后台处理
本文使用下列技术:ASP.NET,.NET 框架,IIS

  用 ASP.NET 编写 Web 应用程序其轻松程度令人难以置信。它是如此的容易,以至于许多开发人员不用花费多少时间来构筑其应用便能获得非常好的性能。在本文中,我将给出10个编写高性能 Web 应用的技巧。我的评论不仅仅局限与 ASP.NET 应用,因为它们只是 Web 应用的一个子集。本文也不是 Web 应用性能调整的权威指南——这方面的内容可以写成一本书。相反,本文可以被视作一个好的起点。
  在废寝忘食地工作之前,我常常要去攀岩。在攀岩之前,我总是要看一下指南手册中的线路并阅读以前来此一游的人留下的建议和忠告。但是,不管指南手册有多磨好,在尝试一次特定的具有挑战性的攀爬之前,你都必须付诸实际的行动。同样,在你面临解决的性能问题或者营运一个高吞吐量的站点之前,你只能想方设法编写高性能 Web 应用程序。
  我们个人经验来自在微软 ASP.NET 团队从事底层架构程序经理,运行和管理 www.asp.net ,并协助架构 Community Server 过程中的经历,Community Server 是几个有名的 ASP.NET 应用程序的下一个版本(它将 ASP.NET Forums,.Text 和 nGallery 整合到一个平台)。我确信这些帮助过我的技巧也会对你有所裨益。
  你应该考虑将应用程序分离成几个逻辑层。你可能听说过术语3-层(或n-层)物理体系结构。它们通常是跨进程和/或硬件对功能进行物理划分的规定的体系结构模式。当系统需要伸缩时,更多的硬件能被添加。然而,总是应该避免与进程和机器忙碌程度相关的性能问题。所以,不管什么时候,只要可能,都要在相同的应用中一起运行 ASP.NET 页面及其相关的组件。
  由于代码和层之间的边界分离,使用 Web 服务或远程调用将降低20%以上的性能。
  数据层则稍微有些不同,因为数据库通常都用专门的硬件。但是,数据库的处理成本仍然很高,因此最优化代码时,数据层的性能应该是首当其充要关注的地方。
  在着手解决你的应用程序的性能问题之前,一定要剖析应用程序,确定问题之所在。获取关键的性能计数器值(如实现垃圾收集所花时间之百分比的性能计数器的值)对于查找应用程序在何处最耗时也是非常重要的。凭借直觉常常也能找到耗时所在。
  本文所描述的性能改进有两种类型:大型优化,如使用 ASP.NET Cache,以及不断重复进行的微型优化。这些微型优化有时很有意思。对代码的小小改动便会引起很大的动静,产生成千次的调用。对于大型优化,你可能会看到整体性能的大跳跃。而对微型优化,给定请求可能只是毫秒级的调整,但按每天的请求总数计算,其结果的改进可能是巨大的。

数据层的性能

  当调整某个应用程序的性能时,有一个简单的试金石,你可以用它按先后次序:检查代码是否存取数据库?如果是,多长时间存取一次?注意相同的测试也可以被应用于使用 Web 服务或远程调用的代码,但我们本文中不涉及这方面内容。
  如果在特定的代码流程中必须具有对数据库的请求以及要考察其它方面,如:想对字符串处理进行优先优化,那么暂且把它放一放,先按照上面定好的优先次序来做。除非你有异乎寻常的性能问题,否则你的时间应该用在尝试最优化与数据库的连接所花的时间,返回的数据量以及多长时间往返一次和数据库的通讯上。
  有了这些概括信息,下面就让我们来看看能帮助你改善应用程序性能的十个技巧。我将从能获得最显著效果的改变开始。

技巧 1 —— 返回多个结果集

  复审你的数据库代码,看看是否有多于一次的对数据库的访问请求。这样每次往返数据库都降低你的应用程序能处理的每秒请求数。通过在单个数据库请求中返回多结果集,你能降低与数据库通信的总体时间。同时你也将使系统更具伸缩性,因为你减少了数据库服务器处理请求的负担。
  虽然你可以用动态 SQL 返回多结果集,我更喜欢使用存储过过程。是否将业务逻辑驻留在存储过程当中是个有待争论的问题,但我认为,如果存储过程中的逻辑能约束返回的数据(降低数据集的尺寸,在网络上传输的时间以及逻辑层不必过虑数据),这是一件好事情。
  使用 SqlCommand 命令实例及其 ExecuteReader 方法来处理强类型的各个业务类,你通过调用 NextResult 可以向前移动结果集指针。Figure 1 示范了处理几个带类型的 ArrayLists 例子会话。从数据库只返回你需要的数据还会降低服务器上内存的分配。

技巧 2 —— 分页数据存取

  ASP.NET DataGrid 提供了非常好的能力:数据分页支持。当启用 DataGrid 中的分页功能,则每次只显示固定数量的记录。此外,分页用户界面也会显示在 DataGrid 底部用于导航记录。分页用户界面允许你向前向后导航所显示的记录,一次显示固定数量的记录。
  有一个美中不足的是用 DataGrid 分页需要将所有数据邦定到此栅格控件(gird)。例如,你的数据层必须返回所有数据,然后 DataGrid 将根据当前页过滤掉所有显示的记录。当你通过 DataGrid 进行分页时,如果有 100,000 条记录被返回,那么每个请求有 99,975 条记录将被废弃掉(假设页尺寸为 25)。当记录数不断增加,此应用程序的性能便会遭受痛苦,因为每次请求所要发送的数据会越来越多。
  编写较好的分页代码的一个好的方法是用存储过程。Figure 2 示范了一个用 Northwind 数据库中 Orders 表通过存储过程分页的例子。很简单,只要你在页面中传递索引以及页尺寸即可。相应的结果集先被计算然后被返回。
  在 Community Server 中,我们编写了几个分页控件来完成数据分页。你将会看到,我使用了技巧 1 中讨论的思路,从一个存储过程中返回连个结果集:总记录数和请求的数据。
  返回的总记录数依赖于所执行的查询不同而不同。例如,某个 WHERE 子句可被用于约束返回的数据。为了计算在分页用户界面显示的总页数,返回的总记录数必须是已知的。例如,如果有 1,000,000 条记录,用一个 WHERE 子句对之过滤后为 1,000 条记录,则分页逻辑必须要知道总记录数以便在分页用户界面中正确呈现。

技巧 3 —— 连接池

  建立 Web 应用程序与 SQL Server 之间的 TCP 连接是一项昂贵的操作。微软的开发人员利用连接池技术已经有好长一段时间了,这个技术使他们能重用到数据库的连接。而不是每次请求都建立新的 TCP 连接,新连接仅在连接池中得不到连接时才建立。当连接被关闭时,它被返回到连接池中,在那里它仍然保持与数据库的连接,与完全断开 TCP 连接相反。
  当然,你需要提防泄漏的连接。当你处理完毕,一定要关闭连接。重申一次:不管人们怎么吹嘘微软 .NET 框架中的垃圾收集特性,每当你处理完毕,一定要显式地调用连接对象的 Close 或 Dispose 方法。不要指望公共语言运行时(CLR)来为你定时清除和关闭连接。CLR 最终将销毁类并强行关闭连接,但你无法保证该对象的垃圾收集届时会起作用。
  为了充分用好连接池,有几条规则必须了然于心。首先,打开连接,进行处理,然后关闭连接。宁愿每个请求的连接打开和关闭多次,也不要保持连接打开状态以及在不同的方法间将它传来传去。其次,使用相同的连接串(如果你使用集成身份检查,那么也要用相同的线程身份)。如果你不用相同的连接串,例如,根据登录用户来定制连接串,你将无法得到连接池所提供的相同的最优化值。当模拟大用户量情形时,如果你使用集成身份检查,那么你的连接池将效力大减。.NET CLR 数据性能计数器在试图跟踪任何与连接池有关的性能问题时是非常有用的。
  不管什么时候,只要你的应用程序连接到运行在其它进程中的资源,比如某个数据库,你都应该针对连接到资源所耗时间,发送和接收数据所耗时间以及往返次数进行优化。为了实现较好的性能,应该首当其充优化应用程序中任何种类的忙碌进程。
  应用层包含到数据层的连接以及将数据转换成有意义的类实例和业务处理的逻辑。以 Community Server 为例,你要在其中处理 Forums 和 Threads 集合;以及应用许可这样的业务规则;尤其重要的是缓冲(Caching)逻辑也实现其中。

技巧 4 —— ASP.NET Cache API

  在编写代码之前要做的头等大事之一是最大限度地构建应用层并发掘 ASP.NET 的 Cache 特性。
  如果你的组件在 ASP.NET 应用程序内运行,那么你只需要在应用程序工程中引用 System.Web.dll 即可。当你需要访问 Cache 时,用 HttpRuntime.Cache 属性(相同的对象也可以通过 Page.Cache 和 HttpContext.Cache 访问)。
  缓冲数据有几个准则。首先,如果数据能被使用多次,缓冲是个好的后选方案。其次,如果数据对给定请求或用户是一般的数据而非专用数据,那么最好是选择缓冲。如果数据用户或请求专用,如果需要保存期很长但可能不被经常使用,那么仍然要用缓冲。第三,常常被忽略的一个准则是有时缓冲太多的东西。一般来说,在x86机器上,为了降低内存不足错误的几率,运行某个进程不要超过800MB私有字节。因此,缓冲应该有个上限。换句话说,你也许能重用某个计算的结果,但如果该计算有10个参数,你可能试图针对10个置换进行缓冲,这样做可能会给你带来麻烦。ASP.NET 提供的最常见的容错是由覆盖缓冲导致的内存不足错误,尤其是大型数据集。
  Cache 有几个重要特性是必须要了解的。第一个是 Cache 实现了最近最少使用(least-recently-used)算法,允许 ASP.NET 强制 Cache 清除操作 —— 如果可用内存下降到低水平 —— 则自动从 Cache 中删除不使用的项目。第二个是 Cache 支持依赖性到期特性,它能强制包括时间,键值,文件失效。时间常常被使用,但 ASP.NET 2.0 引入了具有更强大的失效类型:数据库缓冲失效。也就是当数据库中的数据改变时,缓冲中的条目会自动删除。有关数据库缓冲失效的更多信息参见 Dino Esposito 在 MSDN 杂志 2004 年七月刊的 Cutting Edge 专栏文章。该缓冲的体系结构,参见 Figure 3。

Figure 3 ASP.NET Cache

技巧 5 —— 预请求缓冲(Per-Request Caching)

  在本文前面,我曾提到对频繁执行的代码块所做的小小改动可能产生很大的,整体性能的提升。我把其中一个我特别中意的叫做预请求缓冲(per-request caching)。

时间: 2024-10-31 09:12:29

编写高性能 Web 应用程序的10个技巧的相关文章

编写高性能 Web 应用程序的10 个技巧

web|程序|技巧|性能|技巧|性能 技巧 作者:Rob Howard 本文讨论 • 常见 ASP.NET 性能难点 • 面向 ASP.NET 的有用性能提示和技巧 • 在 ASP.NET 中使用数据库的建议 • 使用 ASP.NET 进行缓存和后台处理 本文使用了以下技术:ASP.NET..NET Framework 和 IIS 本页内容 数据层性能 技巧 1 - 返回多个结果集 技巧 2 - 分页的数据访问 技巧 3 - 连接池 技巧 4 - ASP.NET 缓存 API 技巧 5 - 每请

编写高性能Web应用程序的10个入门技巧

web|程序|技巧|性能 使用 ASP.NET 编写 Web 应用程序的简单程度令人不敢相信.正因为如此简单,所以很多开发人员就不会花时间来设计其应用程序的结构,以获得更好的性能了.在本文中,我将讲述 10 个用于编写高性能 Web 应用程序的技巧.但是我并不会将这些建议仅局限于ASP.NET 应用程序,因为这些应用程序只是 Web 应用程序的一部分.本文不作为对 Web应用程序进行性能调整的权威性指南 - 一整本书恐怕都无法轻松讲清楚这个问题.请将本文视作一个很好的起点. 成为工作狂之前,我原

jQuery Mobile一个极好的框架用于编写移动Web应用程序

jQuery Mobile 是一个极好的框架,用于编写移动 Web 应用程序.jQuery Mobile 构建于流行的 jQuery 和用户界面 (UI) 之上,是一个有效的统一框架,可为您编写移动 Web 应用程序.有了 jQuery Mobile,就可以确保外观.感觉和行为在不同移动平台上的一致性.jQuery Mobile 基本特性包括: 一般简单性和灵活性 该框架易于使用.您可以: 主要使用标记驱开发动页面,无需或仅需很少 JavaScript. 使用高级 JavaScript 和事件.

如何编写高性能的应用程序

程序|性能 在这个硬件性能日新月异的年代里,我们充分的享受着硬件带给我们的"免费午餐",似忽软件的效率问题已经不再是一种被开发者关心的问题,但是,随着CPU的主频提高步伐越来越慢,高速缓存也不是可以无限制增加,新技术的使用逐渐被用来提高硬件的性能,这时候,要充分发挥这些新特性,软件的支持就显得很重要了,于是,程序的运行效率再一次映入我们的视野,新时代的软件优化,我们该何去何从? 看见这篇文章的标题,你可能会说:噢,有必要吗,现在的电脑速度越来越快,何苦去费力写高性能的程序呢?如果程序性

编写ASP.NET应用程序的十大技巧

asp.net|程序|技巧     在本篇文件中,我们将讨论编程人员在使用ASP.NET开发应用程序时需要注意的10个技巧,这些技巧涉及从缺省的控件.表单名的改变到StringBuilder类的使用,有助于编程人员能够尽快地适应.NET环境. 1.在使用Visual Studio .NET时,除直接或非引用的对象外,不要使用缺省的名字    .NET带来的好处之一是所有的源代码和配置文件都是纯文本文件,能够使用Notepad或WordPad等任意的文本编辑器进行编辑.如果不愿意,我们并非一定要使

使用Eclipse调试Java程序的10个技巧

你应该看过一些如<关于调试的N件事>这类很流行的帖子 .假设我每天花费1小时在调试我的应用程序上的话,那累积起来的话也是很大量的时间.由于这个原因,用这些时间来重视并了解所有使我们调试更方便的功能.那能为你省下一些时间,也将会使你的生活更安逸.轻松.同时也表明其它关于此主题的帖子也是很有价值的. 第1条:不要调试太多 一个关于调试的疯狂声明作为开头.但它必须是要说的!尝试切分一下你那复杂的逻辑成多个独立的单元,并编写单元测试来检测你代码的正确性.我想像如下这样的流程应该是发生得非常频繁的---

优化Node.js Web应用运行速度的10个技巧_node.js

Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异常的快.本文将介绍 10 条,经过检验得知可大大提高 Node 应用的技巧.废话不多说,让我们逐条来看看. 1. 并行 创建 Web 应用的时候,你可能要多次调用内部 API 来获取各种数据.比如说,假设在 Dashboard 页面上,你要执行下面这几个调用: 用户信息 -getUserProfil

使用Google Web Toolkit和Eclipse Galileo进行高性能Web开发

您以前可能听说过 Google Web Toolkit (GWT),它支持以 Java 编程语言编写 Web 应用程序,然后将 Web 应用程序编译为 JavaScript 以便在 Web 浏览器中运行.这允许通过利用 Java 的静态类型和 Eclipse 之类的出色工具提高生产力.您也许看到过一些构建在 GWT 上的有用的.流行的小部件.有一点您也许不知道,GWT 支持创建高性能 Web 应用程序. 先决条件 本文将查看几个 GWT 特性,以及这些特性如何帮助您构建高性能 Web 应用程序.

Yote Web应用程序服务器

Yote 是一个采用Perl和http://www.aliyun.com/zixun/aggregation/33906.html">JavaScript编写的Web应用程序服务器.它是专门为Web应用程序的软件开发而设计.它是一个适用于所有用户的开源项目. Yote程序应用于游戏中的一个例子:http://madyote.com/gru/index.html Yote 主要功能包括: .用于连接JavaScript客户端到perl服务器.自动保存到数据存储的对象.客户端可以看到和使用的控