阅读更多

1顶
0踩

编程语言
本文来自:tkb至简

如果你在构建一个面向公众的web站点,那么在项目结尾时你想要实现的就是web负载性能良好。这意味着,你要确保你的产品在高负载下(50个并发用户或者每秒200个用户等等)能够运行,即使你认为此时不会有那么大的负载。久而久之,你的web站点可能吸引越来越多的用户,此时如果web的负载难以让人忍受时,那么自然而然网站开始走下坡路,意味着客户流失以及名誉受损。

那么可以采取哪些措施可以使得一个ASP.NET或者ASP.NET MVC应用更加高性能呢?

早期阶段就要对应用进行负载测试

大多数开发者趋向在应用开发完成后,集成测试和回归测试通过后才进行负载测试。尽管在开发完成后执行一次负载测试好过不做,但是一旦完成了代码的编写,修复性能问题就为时已晚了。这个问题最常见的例子就是当应用程序在负载测试时不能正确响应时,就会考虑向外扩展(增加更多的服务器)。有时这是不可能的,因为代码不适合实现扩展服务器。比如当对象是存储在Session中并不可序列化时,这样添加更多的web节点或者工作者进程就是不可能的。如果你在开发的早期阶段就发现你的应用可能要部署到多台服务器上,那么你应该在配置和服务器的数量等方面都要让测试环境和最终环境尽可能地接近,这样你的代码会更容易适应。

使用高性能类库

近来我在诊断web站点的性能问题时发现了代码中的一个热点问题:来自第三方web服务的JSON信息必须要被反序列化多次。那些Json信息是由Newtonsoft.Json反序列化的,并且证明了Newtonsoft.Json在反序列化时不是最快的类库,然后我们使用了一个更快的类库(如ServiceStack)替代了Json.Net,并获得了更好的结果。

如果我们在挑选了Json.Net作为序列化类库的早期阶段就完成了负载测试,那么我们就会更早地发现性能问题,我们就不必再代码中做这么多的修改了,也不必再次完整地重新测试了。

你的应用是CPU密集还是IO密集的?

在开始实现web应用以及设计项目时,你要首先考虑的一件事就是你的应用是CPU密集的还是IO密集的?这对于了解扩展应用的策略是很重要的。

比如,如果你的应用是CPU密集的,那么你可能想使用同步模式,并行处理等等。然而,对于一个有很多IO受限的操作(例如和外部web服务或者网络资源如数据库通讯)的产品,基于Task的异步模式可能对于向外扩展更有帮助。此外,为了在未来的某天能够创建Web Gardens和Web Farms,你可能想有一个集中式的缓存系统,这样就实现了跨越多个工作者进程或服务的负载。

使用基于Task的异步模型,但要慎重

如果你的产品依赖许多IO受限的操作,或者包括了可能需要消耗宝贵的IIS线程等待一个操作完成的长时间运行的操作,你最好为ASP.NET MVC项目考虑使用基于Task的异步模式。

互联网上有很多关于异步的ASP.NET MVC actions的手册(比如这个),所以这篇博客尽量避免介绍关于异步的知识点。然而,必须指出ASP.NET (MVC)中传统的同步action会造成IIS线程繁忙直到操作完成或请求处理完成。这意味着如果如果web应用在等待一个外部的资源(如一个web服务)响应,那么该线程将是繁忙的。.Net线程池中可以用于处理请求的线程数量也是有限的,因此,尽可能快地释放线程是很重要的。基于Task的异步action或方法会在请求处理后释放该线程,然后从线程池中获取新的线程,并使用该新的线程返回该action的结果。这样,多个请求可以由多个线程处理,这会为你的应用带来更好的响应。

虽然TAP模式对于适当的应用来说很方便,但必须要慎重使用。当你使用TAP设计或者实现一个项目时,必须要注意几个点(你可以点击这里查看),然而,开发者使用async和await关键字面临的最大挑战是知道在这个上下文中他们必须略有不同地处理线程。比如,可以创建一个返回Task(如Task《Product》,博客园的markdown不支持单尖括号)的方法,通常你可以对那个Task调用Run()方法或者只调用task.Result来迫使运行该task,直到拿到结果。

分发缓存和会话(session)状态

开发者在单个开发机器上构建一个web应用是非常常见的,并且也会假设该产品运行在单个服务器上,然而对于面向大众的web通常不是这样的。它们往往被部署到一个叫做负载均衡之后的多个服务器上。尽管你仍然可以使用In-Proc(关于In-Proc和Out-Proc的知识点补充)的模式和粘性(sticky)Session将一个web应用部署到多个服务器上(负载均衡器会将属于相同session的所有请求定向到单个服务器),你可能必须保留session数据和缓存数据的多个副本。比如,如果你将产品部署到由4台服务器组成的web farm上,并且你保持session数据为In-Proc,那时一个请求到达一个已经包含缓存数据的机会是四分之一或25%,然而你如果在正确的地方使用了集中式缓存机制,那么为每个请求找到缓存条目的机会就是100%。这对于严重依赖缓存数据的web应用是至关重要的。

使用集中式缓存机制(像App Fabric或Redis)的另一个好处是对实际的产品实现主动缓存系统的能力。主动缓存机制可以用于在客户端请求一个条目之前就可以将最受欢迎的条目预加载到缓存中。如果你使用实际的数据源来管理缓存同步时,那么这会帮助你大幅地改善大数据驱动应用的性能。

创建Web Gardens

之前提到,在一个IO受限的web应用中包含了很多长时间运行的操作(如web服务的调用),此时你可能想尽可能地释放主线程。默认情况下,每个web应用运行在一个主线程下,该主线程为保持web站点存活(alive)负责,但不幸的是,当它太忙的时候,你的站点就变得不能响应了。给应用添加更多的“主线程”是一种办法,这是通过将更多的工作者进程添加到IIS下的Web站点来实现的。每个工作者进程都会包括一个单独的主线程,因此,如果一个主线程繁忙,还有另外的主线程来处理到来的请求。

拥有多个工作者进程会将你的web站点变成一个Web Garden,这要求你将Session和应用数据持久化到Out-Proc中(例如一个state server或者Sql Server)。



巧妙地使用缓存和懒加载

无需强调,如果你将经常访问的一点数据缓存到内存中,那么这会减少数据库和web服务的调用。正如之前所说,这对于IO受限的应用特别有帮助,当网站处于低负载时可能会造成不幸。

提高站点响应的另一种方式是使用懒加载。懒加载意味着应用里不会有确定的数据片,但是它知道数据在哪里。比如,如果web页面上有一个下拉列表,这意味着要显示一个产品列表,一旦页面加载完毕,不必从数据库中加载所有的产品。你可以在页面中添加一个jQuery函数,该函数可以在第一次下拉时填充下拉列表。你也可以在代码中的许多地方使用相同的技术,比如当使用Linq查询和CLR集合时。

不要在MVC视图中放C#代码

ASP.NET MVC视图会在运行时编译而不是在编译时,因此,如果在视图中包含了太多的C#代码,那么你的代码不会编译后放到dll文件中。这样做不仅有害于软件的可测试性,还会使web应用更慢,因为每个页面都有花更长的时间获得显示(因为它们必须被编译)。将代码添加到视图中的其他缺陷在于它们不能异步运行,这样,如果你决定基于TAP来构建应用时,就不能充分利用视图中的异步方法和action了。

比如,如果你的代码中有这么一个方法:
public async Task<string> GetName(int code)
{

    var result = …

    return await result;

}

该方法可以在一个异步的ASP.NET MVC action的上下文中异步运行,比如:
public Task<ActionResult> Index( CancellationToken ctx )
{
    var name = await GetName( 100 );
}

但是如果在一个视图中调用这方法,因为该视图不是异步的,所以必须以一种线程阻塞(thread-blocking)的方式运行,如:
var name = GetName(100).Result;

.Result会阻塞运行的线程,直到GetName()处理完成了请求,这样该应用的执行会停止一会儿,然而当使用await关键字调用该代码时,该线程不会被阻塞。

适当时使用Fire & Forget

注:Fire & Forget,字面意思是发射,然后忘记,不去理会了。网络释义为射后不理。
如果两个或多个操作没有生成单个事务,那么你很可能不必按顺序运行它们。比如,如果一个用户在你的站点注册时创建了一个账户,一旦他们注册了,你就把他们的详细信息保存到数据库,然后给他们发送一封邮件,你不必等待邮件发送出去才结束这个操作。

在这种情况下,最好的方法很可能就是开启一个新的线程,让它给用户发送邮件,然后返回到主线程。这就叫做Fire& Forget,它可以提高应用的响应能力。

为x64 CPU创建

32-bit的应用局限于较低的内存量和可以访问更少的CPU功能/指令。要克服这些限制,如果你的服务器是64-bit的,那么要确保你的应用运行在64-bit模式下(通过确保在IIS的32-bit模式下运行网站的选项是不是开启)。然后为x64 CPU编译并生成代码而不是Any CPU。

x64有用的一个例子是提高数据驱动应用的响应能力和性能,有一个好的缓存机制是必须的。In-proc是消耗内存的,因为一切都存储在网站的应用程序池的内存边界。对于x86进程来说,可以分配的内存量限制到4GB,这样,如果加载到缓存中,这个限制很快就被打破。如果相同的站点是为x64 CPU显式生成的,那么内存限制就不需考虑了,这样更多的条目可以加到缓存中,然后和数据库的通讯就少了,这会带来更好的性能。

使用服务器上的监视和诊断工具

可能存在你肉眼看不到的更多的性能问题,因为它们不会出现在错误日志中。当应用程序已经部署到基本没有机会调试的服务器上时,识别性能问题是更吓人的事情。

要找出缓慢的处理,线程阻塞,悬挂,错误等等,强烈建议在服务器上安装一个监视和诊断工具,让它们持续地跟踪和监视你的应用程序。我个人使用的是NewRelic检查我的在线网站的健康。获取详细信息并创建免费账号看这里哦!

分析运行中的应用

一旦完成了网站开发,部署到IIS,然后附加一个分析器(如Visual Studio Profiler),然后抓取应用的多个部分的快照。比如抓取购买或者用户注册等操作的快照,然后检查病查看是否存在任何造成缓慢或阻塞的代码。在早期阶段找到那些热点可能会节省你大量的时间,荣誉和金钱。
  • 大小: 70 KB
  • 大小: 27.5 KB
来自: tkb至简
1
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 构建高性能ASP.NET站点

    系列文章连接:构建高性能ASP.NET站点开篇构建高性能ASP.NET站点之一剖析页面的处理过程(前端)构建高性能ASP.NET站点之二优化HTTP请求(前端)构建高性能ASP.NET站点之三细节决定成败开篇网站优化需要考虑的方面在用...

  • 构建高性能ASP.NET站点(上)

    系列文章:构建高性能ASP.NET站点开篇构建高性能ASP.NET站点之一剖析页面的处理过程(前端)构建高性能ASP.NET站点之二优化HTTP请求(前端)构建高性能ASP.NET站点之三细节决定成败构建高性能ASP.NET站点第五章—性能...

  • 构建高性能ASP.NET站点(下)

    系列文章:构建高性能ASP.NET站点第六章—性能瓶颈诊断与初步调优(上篇)—识别性能瓶颈构建高性能ASP.NET站点第六章—性能瓶颈诊断与初步调优(下前篇)—简单的优化措施构建高性能ASP.NET站点第六章—性能瓶颈...

  • 构建高性能ASP.NET站点(中)

    大型高性能ASP.NET系统架构设计构建高性能ASP.NET站点第五章—性能调优综述(中篇)构建高性能ASP.NET站点第五章—性能调优综述(后篇)大型动态应用系统又可分为几个子系统:Web前端系统负载均衡系统数据库集群系统...

  • 构建高性能可扩展ASP.NET网站 Ultra-Fast ASP.NET 4.5 第二版 非扫描英文版

    《构建高性能可扩展ASP.NET网站》第二版,英文版,即《Ultra-Fast ASP.NET 4.5》

  • 构建高性能可扩展ASP.NET网站

    This book’s 11 chapters are designed to be read in succession, but you can jump back and forth between topics and fill in the blanks when necessary. The chapters are organized into the following ...

  • 构建高性能可扩展ASP.NET网站 高清中文版

    《构建高性能可扩展ASP.NET网站》由Richard Kiessig所著,针对ASP.NET网站开发中可能遇到的问题,给出了经过实践检验的具体解决方法。涉及的内容包括:加快显示HTML的方法、缓存的最佳方式、如何使用IIS、如何处理...

  • 构建高性能可扩展ASP.NET网站-中文版

    构建高性能可扩展ASP.NET网站中文版(带目录)。针对ASP.NET网站开发中可能遇到的问题,给出了经过实践检验的具体解决方法。涉及的内容包括:加快显示HTML的方法、缓存的最佳方式、如何使用IIS、如何处理会话状态、...

  • 构建高性能可扩展ASP.NET网站.part1

    构建高性能可扩展ASP.NET网站.part1 构建高性能可扩展ASP.NET网站.part2

  • 《构建高性能可扩展ASP.NET网站》源码

    此为《构建高性能可扩展ASP.NET网站》一书的源码 让ASP.NET + SQL Server网站飞 迅速提升网站性能,全面挖掘网站潜力 微软资深技术专家力作,亚马逊全五星评价 本书针对ASP.NET 网站开发中可能遇到的问题,给出了...

  • 构建高性能可扩展ASP.NET网站PDF与源码(修正PDF)

    上次上传失误,没有包含PDF文档。包含构建高性能可扩展ASP.NET网站源码以及文档

  • [全]构建高性能可扩展ASP.NET网站+代码

    这个是完整版本,有文档有代码,下这一个就好了。 其他的要么缺代码,要么缺文档。

  • ASP.NET AJAX深入浅出系列课程(31):构建高性能ASP.NET AJAX应用程序

    ASP.NET AJAX深入浅出系列课程(31):构建高性能ASP.NET AJAX应用程序

  • 构建高性能可扩展ASP.NET网站(pdf英文版 + SourceCode)

    构建高性能可扩展ASP.NET网站.pdf

  • 打造基于jQuery的高性能TreeView(asp.net)

    根据我的项目实践情况,主要是几个关键点: 1:支持静态的树,即一次性将全部数据加载到客户端。2:异步树,即一次只加载一级或若干级节点,子节点可以异步加载数据。3:Checkbox树(可能是静态树也可能是异步树),...

  • 毕业设计:基于SSM的mysql-羽毛球交流平台系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_羽毛球交流平台系统(源码 + 数据库 + 说明文档) 2 关键技术介绍 6 2.1 JSP技术概述 6 2.2 MYSQL简介 6 2.3 B/S结构 7 2.4 JAVA语言 8 2.5 MyEclipse简介 9 2.6 性能分析 9 2.7 SSM概述 10 3 需求分析与设计 11 3.1 系统需求分析 11 3.2 运行可行性 11 3.3 系统可行性分析 11 3.3.1 技术可行性 11 3.3.2 经济可行性 12 3.3.3 操作可行性 12 3.4 系统功能分析 12 3.5 系统功能结构图 13 3.6 系统流程分析 14 4 数据库设计 17 4.1数据库逻辑结构设计 17 4.2数据库物理结构设计 20 5 系统的详细设计与实现 25 5.1首页页面 25 5.2站内新闻页面 25 5.3场地列表页面 26 5.4场地详情页面 26 5.5在线留言页面 27 5.6修改密码页面 27 5.7注册用户管理信息页面 28 5.8场地信息管理页面 28 5.9场地预约管理页面 29 5.10评论信息管理页面 29 5.11添加友情链

  • node-v10.15.1-win-x64.zip

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

  • VLT 变频器工程指南 danfoss

    VLT 变频器工程指南 Guía de funcionamiento Safe Torque off Convertidores de frecuencia VLT

  • 基于Java的C语言试题生成与考试系统的设计与实现(源代码+论文)

    基于Java的C语言试题生成与考试系统的设计与实现是一个毕业设计题目,旨在通过使用Java编程语言设计和开发一个功能完善的C语言试题生成与考试系统。 该毕业设计题目的背景和意义在于,随着计算机科学的不断发展,C语言作为一门基础编程语言,被广泛应用于软件开发、系统编程等领域。为了更好地评估学生对C语言的掌握程度,传统的纸质试卷已经无法满足需求,因此,开发一个基于Java的C语言试题生成与考试系统具有重要的实际意义。 该毕业设计题目的主要研究内容包括以下几个方面:首先,需要进行系统需求分析,明确系统的功能需求和技术要求。然后,需要进行系统设计,包括数据库设计、模块划分、算法设计等。接下来,需要使用Java编程语言进行系统开发,包括前端界面开发、后台逻辑实现、数据库操作等。最后,需要进行系统测试和优化,确保系统的稳定性和可靠性。 通过完成该毕业设计题目,学生可以深入学习和掌握Java编程语言,提高软件开发能力。同时,学生还可以学习和了解C语言的相关知识,以及试题生成和考试系统的设计与实现方法。这对于学生未来的职业发展具有积极的推动作用。

Global site tag (gtag.js) - Google Analytics