`
az7772010
  • 浏览: 204076 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

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

 
阅读更多

作者:Rob Howard <wbr><wbr>译:寒带鱼</wbr></wbr>


这篇文章讨论了:

·一般视频教程'>asp.NET性能的秘密

·能提高asp.net表现的有用的技巧和窍门

·在ASP.NET中使用数据库的建议

·ASP.NET中的缓存和后台处理

<wbr><wbr><wbr><wbr>使用ASP.NET编写一个Web应用程序是难以置信的简单的。太简单了,以至于很多开发者都不花费时间来构建他们的应用程序来达到很好的表现。在这篇文章里,我将为编写高性能的Web应用程序推荐10个技巧。我不会讲我的论述局限于ASP.NET应用程序,因为ASP.NET应用程序只是Web应用程序的一个子集而已。这篇文章不会是针对优化Web应用程序的性能的权威性指导——一本完整的书可以很容易的做到这一点。相反,我们应该把这篇文章当成一个好的起点。<br><br><wbr><wbr><wbr><wbr>在成为一个工作狂以前,我会经常去攀岩。在做任何攀岩活动之前,我更愿意看看旅行指南里面的路线,再读读那些曾经到过峰顶的人做的推荐。但是,不管旅行指南写的有多好,在尝试一个有挑战性的目标之前,您都需要有实际的攀岩经验。与之相似,当您面临修复性能问题或者运行一个高吞吐量站点的问题时,您只能学习如何编写高性能 Web 应用程序。<br><br><wbr><wbr><wbr><wbr>我的个人经验来自在微软的ASP.NET团队中担任过一名基础程序经理的经历,维护和管理www.asp.net,还有帮助构架Community Server,它是几个著名的ASP.NET应用程序(ASP.NET Forums,.Text,和连接到一个平台的nGallery)的下一个版本。我相信这些曾经帮助过我技巧中的一些也会对您有用的。<br><wbr><wbr><wbr><br><wbr><wbr><wbr><wbr>您应该考虑把您的应用程序分离为几个逻辑层次。您可能已经听说过3层(或者n层)体系结构。这些通常都是规定的结构模式,它们将业务和(或)硬件从物理上进行了功能划分。如果系统需要更大的规模,更多的硬件可以轻松的加进来。然而,那会产生一个与业务和机器跳跃相关联的性能下降,因此我们应该避免它。所以只要可能,尽量在同一个应用程序中运行ASP.NET页面和页面的相关组件。<br><wbr><br><wbr><wbr><wbr><wbr>因为代码的分离和层次之间的边界,使用Web服务或者远程处理会降低性能20%甚至更多。<br><br><wbr><wbr><wbr><wbr>数据层有点与众不同,因为通常情况下,最好具有专用于数据库的硬件。然而,然而进程跳跃到数据库的成本依然很高,因此在数据层的性能是您优化代码时应该首先考虑的。<br><br><wbr><wbr><wbr><wbr>在投入到修复您的应用程序的性能问题之前,确保您要先分析您的应用程序来发现问题的根源所在。关键性能计数器(例如那个指示在执行垃圾收集过程中花费的时间百分比的计数器)在找出应用程序在哪里花费了主要的时间时也是非常有用的。虽然那些花费时间的地方经常是不那么直观的。<br><br><wbr><wbr><wbr><wbr>在这篇文章中我讨论了两种改进性能的方法:大块的优化,例如使用ASP.NET缓存,还有小块的优化,它们经常重复出现。这些小块的优化有时是最有意思的。您对代码的一个小的修改会被调用成千上万次。对大块的优化,您可能会发现整个的性能有了一个大的飞跃。对小块的优化,您可能会缩减了对一个给定请求的几微秒的时间,但是如果把每天的所有的请求累积起来,性能就会得到一个意想不到的改进。<br><p><br></p> <p><br></p> 数据层中的性能<br><wbr><br><wbr><wbr><wbr><wbr>当您要开始优化一个应用程序的性能的时候,有一个决定性的测试您可以优先考虑使用:代码是否要访问数据库?如果是,多长时间访问一次?注意这个测试也可以应用到那些使用Web服务或者远程控制的代码中,但是我不会在这篇文章中涉及那些内容。<br><br><wbr><wbr><wbr><wbr>如果在您的代码中的某个代码路径中要求一个数据库请求,而您发现其他地方您想要优先优化,例如字符串操作,那么停下来然后先执行关键性的测试。除非您有一个性能实在糟糕的问题要处理,否则您的时间会得到更好的利用,如果您把时间花在优化数据库连接的时间,返回的数据量,还有您作的往返数据库的操作中。<br><p><br></p> <p><wbr><wbr><wbr><wbr>现在我已经总体介绍了相关的信息,下面让我们看看10条帮您的应用程序表现更好的技巧。我会从那些对改善性能效果最明显的地方开始说。</wbr></wbr></wbr></wbr></p> <p><br></p> <p>技巧 1——返回多个结果集</p> <wbr><wbr><wbr><wbr><wbr>查看一下您的数据库代码,看看您是否有访问数据库多于一次的请求路径(request paths)。每个这样的往返都回降低您的应用程序每秒可以服务的请求的数量。通过在一次数据库请求中返回多个结果集,您可以减少数据库通信消耗的总时间。在您减少了数据库服务器管理的请求之后,您也会使您的系统更具可升级性。<br><br><wbr><wbr><wbr><wbr>一般您可以使用动态sql语句来返回多个结果集,我更喜欢用存储过程。是否应该把业务逻辑放在存储过程中是存在争议的,但我认为如果一个存储过程中的逻辑可以限制返回的数据(减少数据集的大小,花在网络连接上的时间,并且不需要过滤逻辑层的数据),那它就是好东西。<br><br><wbr><wbr><wbr><wbr>使用一个SqlCommand实例和它的ExecuteReader方法来生成强类型的业务类,您可以通过调用NextResult让结果集指针向前移动。图1展示了一个使用定义的类生成几个ArrayList的示例会话。只从数据库返回您需要的数据会显著地减少您服务器上的内存申请。<br><br><wbr>1// read the first resultset<br><wbr>2reader = command.ExecuteReader();<br><wbr>3<br><wbr>4// read the data from that resultset<br><wbr>5while (reader.Read()) {<br><wbr>6 <wbr><wbr>suppliers.Add(PopulateSupplierFromIDat<wbr>aReader( reader ));<br><wbr>7}<br><wbr>8<br><wbr>9// read the next resultset<br> 10reader.NextResult();<br> 11<br> 12// read the data from that second resultset<br> 13while (reader.Read()) {<br> 14 <wbr><wbr>products.Add(PopulateProductFromIData<wbr>Reader( reader ));<br> 15}<br> 16<br> 17<br><br><br> 技巧 2——分页数据访问<br><wbr><br><wbr><wbr><wbr><wbr>ASP.NET的DataGrid提供了一个非常棒的能力:对数据分页的支持。当在DataGrid中设置了分页,那么将一次显示一个特定数目的结果。此外,用来在结果之间导航的分页UI也会在DataGrid的底部显示出来。分页UI允许您在显示的数据之间向前导航或者向后导航,每页显示特定数目的结果。<br><br><wbr><wbr><wbr><wbr><wbr> 但是有一个小问题。使用DataGrid分页时需要所有的数据都绑定到表格。例如,您的数据层会需要返回所有数据,然后DataGrid要根据当前页填充所有要显示的记录。如果当您在使用DataGrid分页时返回了100,000条记录,每次请求都会丢弃99,975条记录(假设每页的容量是25条记录)。当记录的数量不断增长时,应用程序的性能会受到很大的影响,因为每次请求都必须返回越来越多的数据。<br><p><br></p> <p><wbr><wbr><wbr><wbr>一个写出更好的分页代码的办法是使用存储过程。图2显示了一个示例存储过程,它为Nothwind数据库中的Orders数据表分页。总的来说,在这里所有您需要做的就是传入页的索引和页的容量。数据库会计算出适当的结果集然后返回它们。</wbr></wbr></wbr></wbr></p> <br><wbr>1CREATE PROCEDURE northwind_OrdersPaged<br><wbr>2(<br><wbr>3 <wbr><wbr>@PageIndex int,<wbr><br><wbr>4 <wbr><wbr>@PageSize int<br><wbr>5)<br><wbr>6AS<br><wbr>7BEGIN<br><wbr>8DECLARE @PageLowerBound int<br><wbr>9DECLARE @PageUpperBound int<br> 10DECLARE @RowsToReturn int<br> 11<br> 12-- First set the rowcount<br> 13SET @RowsToReturn = @PageSize * (@PageIndex + 1)<br> 14SET ROWCOUNT @RowsToReturn<br> 15<br> 16-- Set the page bounds<br> 17SET @PageLowerBound = @PageSize * @PageIndex<br> 18SET @PageUpperBound = @PageLowerBound + @PageSize + 1<br> 19<br> 20-- Create a temp table to store the select results<br> 21CREATE TABLE #PageIndex<wbr><br> 22(<br> 23 <wbr><wbr>IndexId int IDENTITY (1, 1) NOT NULL,<br> 24 <wbr><wbr>OrderID int<br> 25)<br> 26<br> 27-- Insert into the temp table<br> 28INSERT INTO #PageIndex (OrderID)<br> 29SELECT<wbr><br> 30 <wbr><wbr>OrderID<br> 31FROM<wbr><br> 32 <wbr><wbr>Orders<br> 33ORDER BY<wbr><br> 34 <wbr><wbr>OrderID DESC<br> 35<br> 36-- Return total count<br> 37SELECT COUNT(OrderID) FROM Orders<br> 38<br> 39-- Return paged results<br> 40SELECT<wbr><br> 41 <wbr><wbr>O.*<br> 42FROM<wbr><br> 43 <wbr><wbr>Orders O,<br> 44 <wbr><wbr>#PageIndex PageIndex<br> 45WHERE<wbr><br> 46 <wbr><wbr>O.OrderID = PageIndex.OrderID AND<br> 47 <wbr><wbr>PageIndex.IndexID &gt; @PageLowerBound AND<br> 48 <wbr><wbr>PageIndex.IndexID &lt; @PageUpperBound<br> 49ORDER BY<wbr><br> 50 <wbr><wbr>PageIndex.IndexID<br> 51<br> 52END<br> 53<br> 54<br><br><wbr><wbr><wbr> 在社区服务期中,我们写了一个分页服务端控件来做这些数据分页。您会发现我在使用技巧1中讨论过的思想,从一个存储过程返回两个结果集:纪录总数和请求的数据。<br><br><wbr><wbr><wbr><wbr>返回的记录总数可以根据执行的请求而有所不同。例如,一个WHERE分句可以用来约束返回的数据。我们必须知道要返回的记录总数,以计算要在分页UI中显示的总的页数。例如,如果有1,000,000条总的记录数,而一个WHERE分句用来把这些记录过滤为1,000条记录,分页逻辑需要知道总的记录数来恰当的提交分页UI。<br><br><br> 技巧 3——连接池<br><wbr><br><wbr><wbr><wbr><wbr>在您的Web应用程序和SQL Server之间建立TCP连接会是一个昂贵的操作。Microsoft的开发者们已经利用连接池有一段时间了,这允许他们重用与数据库的连接。与其为每个请求建立一个新的TCP连接,还不如只有在连接池中没有一个可用的连接的时候才建立一个新的连接。当连接关闭后,它返回到连接池中——它还保持着与数据库的连接,而不是完全销毁那个TCP连接。<br><br><wbr><wbr><wbr><wbr><wbr><wbr>当然您需要小心泄露的连接。总是关闭您的连接在您使用完它们时。我重复一遍:不管谁说了关于Microsoft .NET框架的垃圾回收机制的什么话,当您使用完时,您务必总是对您的连接显式调用Close或者Dispose方法。不要相信通用语言运行时(CLR)会在一个预定的时间为您清理和关闭您的连接。CLR会最终销毁类并且强迫连接关闭,但您不能保证什么时候在对象上的垃圾回收机制会真正执行。<br><br><wbr><wbr><wbr><wbr>要想使用连接池达到最佳效果,您需要遵循几条规则。第一,打开一个连接,完成工作,然后关闭连接。如果您不得不(最好应用技巧1)为每个请求打开和关闭几次连接也是可以的,这比一直开着连接然后把它传递给几个不同的方法要好得多。第二,使用同一个连接字符串(如果您在使用集成身份认证,当然还需要有相同的线程标识)。如果您不使用同一个连接字符串,例如基于登录的用户的不同自定义连接字符串,您就不能得到连接池提供的相同的最优值。而且如果您在模仿大量的用户时使用了集成身份验证,您的连接池的效率也会降低很多。在尝试跟踪任何与连接池有关的性能问题时,.NET CLR数据性能计数器会很有用的。<br><br><wbr><wbr><wbr><wbr>不论何时您的应用程序连接一个资源,例如一个数据库,或者在另一个进程中运行,您都应该通过把注意力集中到连接到资源所花费的时间上,发送和接受数据花费的时间,还有往返与数据库的次数来进行优化。优化您的应用程序中的任何类型的进程跳转(process hop)都是开始达到更好性能的第一步。<br><br><wbr><wbr><wbr><wbr>应用层包含连接到您的数据层的逻辑,并且把数据转换为有意义的类实例和逻辑过程。例如,在社区服务器中,这里是您生成一个论坛或者线程集合,并且应用业务规则例如许可的地方;更重要的是这里是执行缓冲逻辑的地方。<br><br><p><br></p> <p>技巧 4——ASP.NET缓冲API</p> <p><wbr><wbr><wbr><wbr><wbr><wbr>在您开始编写应用程序的第一行代码之前要考虑的第一件事情是,架构应用层来最大化并且利用ASP.NET的缓存特性。</wbr></wbr></wbr></wbr></wbr></wbr></p> <br><wbr><wbr><wbr><wbr>如果您的组件运行在一个ASP.NET应用程序之中,您只需要在您的应用程序项目中简单的引用System.Web.dll就可以了。当您需要访问缓存时,使用HttpRuntime.Cache属性(这个对象也可以通过Page.Cache和HttpContext.Cache来访问)。<br><br><wbr><wbr><wbr>使用缓存数据有几条原则。第一,如果数据可以多次使用,那么缓存它就是一个好的选择。第二,如果数据是通用的而不是给特定的请求或者用户使用的,那么缓存它就是一个非常好的选择。如果数据是用户或者请求特定的,但是他的生存期是很长的,那么它也可以被缓存,但是可能不会经常使用到。第三,一个经常被忽视的原则是,有时候您可以缓存的太多了。通常在一台x86计算机上,为了减少发生内存不足(out-of-memory)错误的可能性,您会希望运行一个使用不超过800MB私有字节的进程。因此,缓存应该受到限制。换句话说,您可能需要重新使用一次计算的结果,但是如果那个计算需要十个参数,您可能需要尝试缓存10个排列,而这可能会给您带来麻烦。由于过度缓存引起的内存不足错误是ASP.NET中最常见的,特别是对于大数据集的情况。<br><wbr><wbr><br><wbr><wbr><wbr> 缓存有几个极佳的功能,您需要对它们有所了解。首先,缓存会实现最近最少使用的算法,使得 ASP.NET 能够在内存运行效率较低的情况下强制缓存清除——从缓存自动删除未使用过的项目。第二,缓存支持可以强制失效的过期依赖项。这些依赖项包括时间、键和文件。时间经常会用到,但是对于 ASP.NET 2.0,引入了一个功能更强的新失效类型:数据库缓存失效。它指的是当数据库中的数据发生变化时自动删除缓存中的项。有关数据库缓存失效的详细信息,请参阅 MSDN Magazine 2004 年 7 月的 Dino Esposito Cutting Edge 专栏。要了解缓存的体系结构,请参阅图 3。<br><br><br> 技巧 5 — 每请求缓存<br><wbr><br><wbr><wbr><wbr><wbr>在本文前面部分,我提到了对经常遍历代码路径的一些小改善可以获得较大的整体性能收益。对于这些小改善,其中有一个绝对是我的最爱,我将其称之为“每请求缓存”。<br><br><wbr><wbr><wbr><wbr>缓存 API 的设计目的是为了将数据缓存较长的一段时间,或者缓存至满足某些条件时,但每请求缓存则意味着只将数据缓存为该请求的持续时间。对于每个请求,要经常访问某个特定的代码路径,但是数据却只需提取、应用、修改或更新一次。这听起来有些理论化,那么我们来举一个具体的示例。<br><br><wbr><wbr><wbr><wbr>在社区服务器的论坛应用程序中,页面上使用的每个服务器控件都需要个性化的数据来确定使用什么外观、使用什么样式表,以及其他个性化数据。这些数据中有些可以长期缓存,但是有些数据却只针对每个请求提取一次,然后在执行该请求期间对其重用多次,如要用于控件的外观。<br><br><wbr><wbr><wbr><wbr>为了达到每请求缓存,请使用 ASP.NET HttpContext。对于每个请求,都会创建一个 HttpContext 实例,在该请求期间从 HttpContext.Current 属性的任何位置都可访问该实例。该 HttpContext 类具有一个特殊的 Items 集合属性;添加到此 Items 集合的对象和数据只在该请求持续期间内进行缓存。正如您可以使用缓存来存储经常访问的数据一样,您也可以使用 HttpContext.Items 来存储只基于每个请求使用的数据。它背后的逻辑非常简单:数据在它不存在的时候添加到 HttpContext.Items 集合,在后来的查找中,只是返回 HttpContext.Items 中的数据。<br><wbr><br><br> 技巧 6 — 后台处理<br><wbr><br><wbr><wbr><wbr><wbr>通往代码的路径应该尽可能快速,是吗?可能有时您会发现您正在执行的针对每个请求执行的或者每 n 个请求执行一次的任务所需资源非常多。发送电子邮件或者分析和验证传入数据就是这样的一些例子。<br><br><wbr><wbr><wbr><wbr>剖析 ASP.NET Forums 1.0 并重新构建组成社区服务器的内容时,我们发现发布新帖子的代码路径非常慢。每次发布新帖子的时候,应用程序首先需要确保没有重复的帖子,然后必须使用“坏词”筛选器分析该帖子,分析帖子的字符图释,对帖子添加标记并进行索引,请求时将帖子添加到合适的队列,验证附件,最终在帖子发布之后,立即向所有订阅者发出电子邮件通知。很清楚,这涉及很多操作。<br><br><wbr><wbr><wbr><wbr>经研究发现,大多数时间都花在了索引逻辑和发送电子邮件上。对帖子进行索引是一个非常耗时的操作,人们发现内置的 System.Web.Mail 功能要连接 SMTP 服务器,然后连续发送电子邮件。当某个特定帖子或主题领域的订阅者数量增加时,执行 AddPost 功能所需的时间也越来越长。<br><br><wbr><wbr><wbr><wbr>并不需要针对每个请求都进行电子邮件索引。理想情况下,我们想要将此操作进行批处理,一次索引 25 个帖子或者每五分钟发送一次所有电子邮件。我们决定使用我曾经用于对数据缓存失效进行原型设计的代码,这个失效是最终被包含进了Visual Studio 2005之中。<br><br><wbr><wbr><wbr><wbr>System.Threading 命名空间中的 Timer 类非常有用,但是在 .NET Framework 中不是很有名,至少对于 Web 开发人员来说是这样。创建之后,这个 Timer 类将以一个可配置的间隔针对 ThreadPool 中的某个线程调用指定的回调。这就表示,您可以对代码进行设置,使其能够在没有对 ASP.NET 应用程序进行传入请求的情况下得以执行,这是后台处理的理想情况。您还可以在此后台进程中执行如索引或发送电子邮件之类的操作。<br><br><wbr><wbr><wbr><wbr>但是,这一技术有几个问题。如果应用程序域卸载,该计时器实例将停止激发事件。另外,因为 CLR 对于每个进程的线程数量具有一个硬性标准,所以在负载很重的服务器可能会出现这样的情形:其中的计时器可能不能保证线程继续完成操作,并且在某种程度上可能会造成延迟。ASP.NET 通过在进程中保留一定数量的可用线程,并且仅使用总线程的一部分用于请求处理,试图将上述情况发生的机会降到最低。但是,如果您具有很多异步操作时,这可能就是一个问题了。<br><br><wbr><wbr><wbr><wbr>这里没有足够的空间来放置该代码,但是您可以下载一个容易理解的示例,网址是www.rob-howard.net。请了解一下 Blackbelt TechEd 2004 演示中的幻灯片和演示。<br><br><p><br></p> <p>技巧 7 — 页输出缓存和代理服务器<br><wbr><br><wbr><wbr><wbr><wbr>ASP.NET 是您的表示层(或者说应该是您的表示层);它由页、用户控件、服务器控件(HttpHandlers 和 HttpModules)以及它们生成的内容组成。如果您具有一个 ASP.NET 页,它会生成输出(HTML、XML、图像或任何其他数据),并且您针对每个请求运行此代码时,它都会生成相同的输出,那么您就拥有一个可用于页输出缓存的绝佳备选内容。<br><br><wbr><wbr><wbr><wbr>通过将下面这行内容添加页的最上端:<wbr><br><br> &lt;%@ Page OutputCache VaryByParams="none" Duration="60" %&gt;<wbr><br><wbr><br><wbr><wbr><wbr><wbr>您就可以高效地为此页生成一次输出,然后对它进行多次重用,时间最长为 60 秒,此时该页将重新执行,输出也将再一次添加到 ASP.NET 缓存。通过使用一些低级别可编程API 也可以完成此行为。对于输出缓存有几个可配置的设置,如刚刚讲到的 VaryByParams 属性。VaryByParams 刚好被请求到,但还允许您指定 HTTP GET 或 HTTP POST 参数来更改缓存项。例如,只需设置 VaryByParam="Report" 即可对 default.aspx?Report=1 或 default.aspx?Report=2 进行输出缓存。通过指定一个以分号分隔的列表,还可以指定其他参数。<wbr><br><br><wbr><wbr><wbr><wbr>很多人还没有意识到当使用了输出缓存之后,ASP.NET 页也会生成一些向下流到缓存服务器的 HTTP 标题头,如 Microsoft Internet Security 和 Acceleration Server 或 Akamai 使用的标题头。设置了 HTTP 缓存表题头之后,可以在这些网络资源上对文档进行缓存,客户端请求也可在不必返回原始服务器的情况下得以满足。<br><br><wbr><wbr><wbr><wbr>因此,使用页输出缓存不会使得您的应用程序效率更高,但是它可能会减少服务器上的负载,因为下行流缓存技术会缓存文档。当然,这只能是匿名内容;一旦它成为下行流之后,您就再也不会看到这些请求,并且再也无法执行身份验证以阻止对它的访问了。<br><br><br><br> 技巧 8 — 运行 IIS 6.0(哪怕只为了使用内核缓存也好)<br><wbr><br><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></p></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
分享到:
评论

相关推荐

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

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

    编写高性能WEB的十个技巧

    在本文中,我将给出10个编写高性能 Web 应用的技巧。我的评论不仅仅局限与 ASP.NET 应用,因为它们只是 Web 应用的一个子集。本文也不是 Web 应用性能调整的权威指南——这方面的内容可以写成一本书。相反,本文可以...

    ASP NET性能高级编程(PDF)

    全书共包括9章和1个附录,书中首先讨论了性能的概念和性能的重要性,然后逐步讲解性能的设计,编写高性能代码的原则和实例,如何提高数据处理、数据访问、数据操作和数据表示的性能,使用WAS和ACT工具测试应用程序,...

    编写高性能Java代码的最佳实践

    在这篇文章中,我们将讨论几个有助于提升Java应用程序性能的方法。我们首先将介绍如何定义可度量的性能指标,然后看看有哪些工具可以用来度量和监控应用程序性能,以及确定性能瓶颈。我们还将看到一些常见的Java代码...

    [整站程序]8优技巧网_8ujq.zip

    通过以上技术选择和框架搭建,该项目可以实现一个高性能、可扩展性强的Web应用程序。开发人员可以基于框架提供的功能和组件进行快速开发,减少重复代码的编写,提高开发效率。同时,使用MySQL作为数据存储,可以保证...

    hiboot:hiboot是具有依赖项注入支持的高性能Web和cli应用程序框架

    Hiboot是用Go编写的云原生Web和cli应用程序框架。 Hiboot并没有尝试重塑一切,它集成了流行的库,但是使它们更简单,更易于使用。 它借用了一些Spring功能,例如依赖项注入,面向方面的编程和自动配置。 您可以通过...

    Linux高性能服务器编程

    由资深Linux软件开发工程师撰写,从网络协议、服务器编程核心要素、原理机制、工具框架等多角度全面阐释了编写高性能Linux服务器应用的方法、技巧和思想。不仅理论全面、深入,抓住了重点和难点,还包含两个综合性...

    delphi 开发经验技巧宝典源码

    0237 如何实现一个应用程序只能打开一个进程 158 7.4 其他数据处理技术 159 0238 对计算结果四舍五入 159 0239 获取一个字符的ASCII值 159 0240 判断字符串中是否有文字符 160 0241 如何从字符串中提取...

    编写可维护的JavaScript中文完整版+英文版

    他著有《JavaScript高级程序设计》、《Ajax 高级程序设计》和《高性能JavaScript》。 李晶,花名拔赤,淘宝前端工程师,具有多年前端开发经验,在团队协作、组件开发、移动Web App等方面有深入研究,曾经参与淘宝...

    PHP和MySQL Web开发第4版pdf以及源码

    4.1 创建一个示例应用程序:智能表单邮件 4.2 字符串的格式化 4.2.1 字符串的整理:chop()、ltrim()和trim() 4.2.2 格式化字符串以便显示 4.2.3 格式化字符串以便存储:addslashes()和stripslashes() 4.3 用...

    PHP和MySQL WEB开发(第4版)

    4.1 创建一个示例应用程序:智能表单邮件 4.2 字符串的格式化 4.2.1 字符串的整理:chop()、ltrim()和trim() 4.2.2 格式化字符串以便显示 4.2.3 格式化字符串以便存储:addslashes()和stripslashes() 4.3 用字符串...

    C++实现线程池详解(基于boost源码以及封装等线程池)

    一、要实现高效的线程池,可以考虑以下几点 二、实现线程池可以按照以下步骤进行 三、简单的C++线程池代码示例 四、 基于boost编写的源码库 - 线程池 4.1 基于boost编写的源码库地址 ...8.3 案例三:高性能Web服务器

    Oracle 10g 网格数据库研讨会33个PPT下载

    用Oracle 数据库10g构建高性能的企业XML应用系统 在亚太区,Oracle坚不可摧的Linux支持 技术-Linux 在亚太区,Oracle坚不可摧的Linux支持 技术-translated 自我管理数据库-自动的SQL调优 自我管理数据库-自动...

    基于ElasticSearch+Spark 构建高相关性搜索服务&千人千面推荐系统.zip

    我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程。在学习的过程中,我遇到了一些挑战,比如配置文件的理解和注解的正确使用,但通过查阅官方文档和阅读相关书籍,我...

    C#微软培训资料

    第三章 编写第一个应用程序 .20 3.1 Welcome 程序 .20 3.2 代 码 分 析 .20 3.3 运 行 程 序 .23 .4 添 加 注 释 .25 3.5 小 结 .27 第二部分 C#程序设计基础.28 第四章 数 据 类 型 .28 4.1 值 类 型...

    Visual.Basic.2010.&.NET4.高级编程(第6版)-文字版.pdf

    13.4.4 编写使用者应用程序的代码 531 13.5 使用数据协定 533 13.6 名称空间 535 13.6.1 建立主机应用程序 535 13.6.2 建立使用者应用程序 536 13.6.3 查看hellocustomerservice的wsdl和架构 538 13.7 ...

Global site tag (gtag.js) - Google Analytics