Internet 信息服务

扩展 ASP.NET 应用程序:经验教训

Richard Campbell

 

概览:

  • 开发人员/IT 协作的重要性
  • 了解主体扩展策略
  • 在团队内共享知识
  • 就核心知识集达成共识

目录

扩展的基础知识
交流想法
网络人员需要了解的开发知识
开发人员需要了解的网络知识
重回扩展
协同灭火

作为顾问,我曾参与的每一次 ASP.NET 应用程序成功扩展都是开发人员(构建者)与网络管理员(实际运行者)之间协作的结果。遗憾的是,这种必要的协作在应用程序

生命周期初始并不总是很明显。因此,在应用程序生命周期开始时我参与的机率很小,只有在最终出现问题的时候才有机会介入。

没有任何应用程序第一次就能得到有效扩展,所有适宜的条件并非能唾手可得,这是个简单的事实。为成功扩展某个应用程序,您需要了解该应用程序的构建方式以及其运行所处操作环境的工作原理。换句话说,您既需要来自开发人员的信息,也需要来自网络人员的信息。没有这种综合知识,成功只是个幻想。

扩展的基础知识

在深入研究之前,让我们先为实际扩展 ASP.NET 应用程序打好基础。通常有两种基本策略可以采用,即规范化和分发,大多数大型可扩展 ASP.NET 应用程序都使用这两种策略。此外,本书中可帮助您扩展 ASP.NET 应用程序的每个技巧均可划分为其中的某一个策略。

规范化需要分隔应用程序的元素,以使其可以单独扩展。例如,您可以构建专用的映像服务器,而不是使用呈现 ASP.NET 页面的相同服务器。映像服务器的最佳配置与 ASP.NET 服务器完全不同。此外,如能将您的映像请求从应用程序的其余部分分离出来,就可以使用第三方资源来提供映像其他资源文件也可采用这种方法。

而分发涉及在多个服务器(通常称为 Web 场)中均衡传播应用程序。ASP.NET 应用程序特别适合分发,因为每个页面请求相对较小,而且指定用户的交互大部分独立于其他用户。分发实际上是“向外扩展”原理的体现,即多个性能一般的服务器共同为用户提供服务,而不是“向上扩展”方法(由一个超强的服务器完成这项工作)。

将规范化和分发结合在一起会提高效率,您可以只分发应用程序中那些对性能要求高的元素。例如,如果您已经创建了专门的映像服务器,但映像服务还够,您可以添加映像服务器,而不是针对整个应用程序添加服务器。当您深入研究改进 ASP.NET 应用程序的性能和可扩展性时,将这些策略铭记在心是非常重要的。

交流想法

在每个 ASP.NET 应用程序生命周期内的某些时候,开发人员和网络/IT 人员可能要举行会议。如果幸运的话,这将在应用程序部署之前进行,但有时只有在发生了危机之后才会进行,例如,应用程序在测试环境中运行良好,但发给用户之后运行非常缓慢(这时我这样的顾问就该登场了)。

开发人员和网络人员开会主要是为交换信息。开发人员对应用程序非常了解,就像网络人员了解操作环境一样。每个小组都需要了解另一小组的数据,他们在应用程序生命周期内越早交流,效果就越好。

这种会议不应是在危机时刻才首次召开。两个团队之间如果没有深入了解,就很难找出应用程序未按要求执行的原因。而且,为了摆脱责任,认为另一方对问题负完全责任的情况是相当容易出现的。这种态度是极不公正的,因为任何极其复杂的问题总是需要双方共同来解决的。

然而,即使在万事顺利的时候,这样的会议也可能是极具挑战性的。我编排的会议通常是网络人员和开发人员分别位于桌子的两侧。他们相互对视。为展开交流,我点明会议的主旨:相互汲取知识。谁先发表意见都没关系。我首先介绍网络需要从开发中了解的内容。

网络人员需要了解的开发知识

每个 ASP.NET 应用程序都有其自己的特点,但有一些关键元素适用于所有情况。web.config 文件便是其中之一(请参见图 1)。Web.config 是开发与网络之间的交点。它有时是由开发人员配置的,有时是由网络人员配置的。不管怎样,web.config 中包含的内容对硬件和网络配置都施加了限制,且直接影响应用程序的运行方式。详细探究 web.config 文件的每个小细节都需要整本书的篇幅;此处重点强调两个组均需要研究 web.config 文件并就其所代表的配置达成一致,而且还要就各种设置对应用程序和环境的影响达成一致。

fig01.gif

图 1 显示一些应用程序设置和自定义错误配置的基本 web.config(单击图像可查看大图)

例如,web.config 的 <authorization> 部分指定将如何在应用程序中对用户进行身份验证,因而定义了依赖关系。如果应用程序使用 Windows® 身份验证,它可能要依靠 Active Directory®。如果它使用基于窗体的身份验证,则依赖用户帐户的数据存储。这的确是很值得交流的。

<customErrors> 部分很值得注意,因为它会影响向用户显示失败信息的方式。这并不是一个复杂的设置,但讨论它可以了解将会有什么样的错误页面。在协作早期可能不会出现任何自定义错误页面,这也是值得讨论的一个议题。

web.config 的 <appSettings> 部分尤为重要。这通常是开发人员存储全局值(例如,数据库的连接字符串)的位置。它不但是依赖关系的支柱,还会在计划故障转移、迁移等项目时发挥重要的作用。但由于 <appSettings> 部分是完全自定义的,因此它可以包含任何内容,并可能需要许多说明才能了解其中的内容。此部分通常留有一些孤立对象,即实际上没有在应用程序的任何位置使用过的值。

即使您的开发人员没有使用 <appSettings>,但网络/操作人员可能希望他们这样做,因为将所有数据库连接字符串置于其中是创建简单故障转移策略的有效途径。如果一个数据库服务器出现故障,可以插入替换字符串以指向其他数据库服务器。在开发伊始抓住这个机会就可以提高应用程序的可靠性和可维护性。

最后,您应注意:从扩展角度来看,web.config 中的绝对关键值是 <sessionState> 标记,它确定应用程序的会话数据存储位置。默认情况下,会话数据的存储模式为 "InProc" 或存储在 ASP.NET 应用程序的进程空间中。如果会话数据是针对进程内而配置的,则所有负载平衡必将“非常棘手”,必须始终将指定用户返回会话数据所驻留的服务器。开发人员和网络人员就此有着广泛的讨论,因为它直接影响您的扩展方式和故障转移方式。及早对此进行研究可以减轻调试应用程序的压力。

讨论一旦涉及会话状态,一般来讲很容易就会转向应用程序的负载平衡要求。一些环境有专用的负载平衡硬件,这些硬件具备特定功能,但如果应用程序无法使用这些功能,它们就没有意义。我曾遇到过硬件负载平衡与具有进程内会话数据的 ASP.NET 应用程序搭配使用的情况。结果是偶尔会莫明其妙地丢失一些会话。它看起来像是应用程序内的一个 Bug,但其实是配置错误。

网络人员需要清楚了解开发流程为应用程序准备的负载平衡架构。这无疑是一个双向对话:有哪些负载平衡架构可供使用以及应用程序可以采用哪一个架构。如在应用程序生命周期早期进行这种交流,您可以预先计划一个独立的进程外负载平衡架构,这是一项很大的优势。

当 ASP.NET 应用程序准备部署(或者初始部署)时,开发人员将非常了解应用程序各组件的运行速度。最重要的是,他们掌握系统中存在的瓶颈和潜在危机点。如果网络/操作团队了解这些瓶颈,他们便可以提前准备应对这些问题,甚至可以将其转移。

例如,我曾使用过一个应用程序,在应用程序的停机时间内每晚都有一个加载大量数据的进程。开发人员构建了数据加载机制、对其进行了测试并了解其工作原理。他们知道这会对数据库造成很大的压力,但这是解决问题的有效方法。

但他们从未告诉过网络团队会发生这一进程,或者他们已将其设计为在凌晨 1 点运行(恰好是数据库备份运行的时间)。数据库保持联机,但它在备份期间运行得十分缓慢,因为所有发送给数据库的事务都将保留在事务日志中。

直到同时进行数据加载和备份导致数据库事务日志卷用尽了磁盘空间时,才发现有冲突。将数据加载改为在凌晨 3 点启动就完全解决了这一问题,但这时危机已发生了几天。

及早对应用程序中的此类工作负荷项目进行交流可以减少许多后期的麻烦。

开发人员需要了解的网络知识

在网络人员向开发人员介绍他们的工作范畴时,我喜欢以网络图为出发点。开发人员经常看到的是如图 2 所示的网络,实际上没有任何网络,只不过是一些 Web 服务器、浏览器和 Internet。

fig02.gif

图 2 开发人员的简单网络构想(单击图像可查看大图)

当然,实际情况要远为复杂。图 3 所示也是个简化图,但更接近于实际。当您查看图 3 的时候,立即会产生一些疑问,例如,“虚拟专用网络 (VPN) 用户如何使用应用程序”或“内部用户与公共用户在身份验证方面有何差别”等。

fig03.gif

图 3 开发人员需要了解的实际网络(单击图像可查看大图)

显然,仅仅提供网络图是不够的。对网络进行详细说明也是非常重要的,因为仅仅查看图表,无法准确了解哪些元素将影响应用程序。您需要介绍公共用户、VPN 用户和内部用户的实际连接过程。讲述现有的各种防火墙规则(尤其是在更复杂的 DMZ 式网络体系结构中)通常会引发应用程序的潜在问题。

很明显,在对应用程序进行部署之前(甚至在开发启动之前)展开所有这些讨论是很有好处的,并且是必要的,关键是让与会的每一个人都了解整个网络图。

网络还是故障转移和冗余模型的领地,但是如果没有一些软件支持或至少了解行为方式,这些模型很少会按计划工作。因此需详细介绍故障的各种表现形式。如果数据库中出现了群集,这将影响与访问数据库相关的代码。例如,可以在切换服务器后重试查询吗?如果存在冗余站点,如何将数据复制到此站点?如何从一个站点切换到另一个站点?

再次重申,这种交流越早越好,迟来强过不来,应用程序中涉及的所有人员都必须了解它们的工作原理。如果故障转移解决方案在需要时却不真正起作用,那真是糟糕透顶。

最后,还有另一种需要共享的重要网络资源,即生产日志。我始终建议将生产日志提供给开发团队。网络人员对此请求的通常反应是“向我索要这些生产日志,我便会将其发送给您”。我认为这是不够的,让开发人员自己拥有检索日志的能力(通常从备份站点)是更有效的方式。

生产日志在出现危机时是必不可少的。它们通常是记录实际情况的最佳真实经验数据来源,也是唯一的来源。在一些更寻常的情况中它们具有同样的价值。当开发人员例行访问生产日志时,他们可能会对其进行彻底检查以了解新功能的工作方式。它非常适合发现您的功能没有按预期执行,并在发生危机之前纠正问题。当每个人都访问日志时,您可以更快速地对问题做出反应并尽早修复它们。

重回扩展

网络与开发之间的会议是要了解扩展 ASP.NET 应用程序所涉及的所有问题。应用程序运行的实际环境直接影响应用程序运行代码的工作方式。与扩展相关的所有策略都将影响其在该环境下的行为。应用专业化策略(例如,分离出应用程序与 SSL 相关的部件)可能需要对网络环境进行更改并对服务器本身进行更改。

甚至看似以代码为中心的更改(如使用缓存)也可能会影响环境。这是因为当您向 ASP.NET 应用程序添加数据缓存时,您在增加内存使用率的同时也降低了数据库调用的次数。结果是您可能增加了所需的 ASP.NET 服务器数或者增加了服务器上的工作线程回收数,这将在网络监视端触发事件。

扩展 ASP.NET 应用程序确实会影响开发和网络人员,因此,让他们参与决策过程是非常值得的。通常,这种协作将产生团队单独工作时不会发现的初始解决方案。例如,网络人员可了解公司内可能有助于开发人员达到性能和扩展要求的现有硬件解决方案。交流应用程序和环境的细节就能促成这些机会。

协同灭火

扩展 ASP.NET 应用程序的资源

扩展中出现的危机并不一定是件坏事情,实际上,它通常会带来一些益处,因为它是由于太多用户想运行您的应用程序而引起的,这是应用程序价值的良好佐证!但前提是应用程序必须能够工作。

有时扩展危机是由另一原因引起的,如您的公司正在进行促销、您成为博客中的焦点,或者社交网站一下将大量人员引向您的网站。您突然间必须面对保持应用程序运行这一艰巨的任务。您可能已经猜到,最好不让这种情况实际出现。开发人员和网络人员在会议上如能通过协作帮助组织应对这种危机,那是最好的结局。

要管理这种危机,第一个问题就是“我们如何检测到站点正处于负荷过重的状态?”最常遇到的情形是“我们接到 CTO 的电话”。如果最早告诉您网站出问题的消息是从外面传来的,那您就有麻烦了。电话响铃之前应该能通过某个适当的检测抢先发现问题。那当然,您仍然会接到报告问题的电话,但它至少可以为您解答问题提供一些帮助。对 CTO 说“噢?真的吗?”可不会给他留下什么好印象。

接下来的问题是:谁第一个接到电话?谁对事件做出回答?通常网络人员会接到第一个警告,但这个人可能相对缺乏经验,因此需要一个明确的上报计划。接下来要通知谁呢?如何快速进行早期诊断以查明您所面临的是何种问题,这是个不小的挑战。如果它是网络中断问题,是一种情况。但如果是扩展问题,则完全是另外一回事情。对于扩展问题,建议尽早地让开发团队的人员参与进来。

参加解决问题的每个人都需要良好的信息,因此有效的访问权限是关键所在。要尽可能多地分发信息,以便进行有效的诊断,并最终确定解决方案的范围。

通常,如果唯一的答案是编写代码,那么事件将在可以编写代码之前结束。当然应当对事件做记录,以便将来帮助确立开发优先级,但编写一大堆代码并在没有仔细测试的情况下将其投入生产是非常不合理(或明智)的做法。灭火的第一条规则都是不要让火势继续蔓延。

对于扩展问题而言,有时解决方案就是等它结束。但仍需要做出一项决策。

同时,计划这些紧急情况意味着可以快速应用多种技术。让网络和开发资源共同解决扩展问题常常可在非常合适的时机解决问题,甚至可能快到给促销带来更大的成功。

总之,从网络端吸取的教训就是高扩展、性能良好的 ASP.NET 应用程序代表构建该应用程序的人员与部署和操作人员之间的成功协作。

由于这种协作是不可避免的,因此最好尽早在两个团队之间召开会议,以便共享信息。会议的目标是了解应用程序的所有元素(功能、工作原理、所依赖的内容、在负载下的行为方式以及其应付逐渐出现的问题的方式)并达成一致。

当这种协作真正起作用时,会大大提高公司的反应速度,塑造一个在未来继续取得成功的公司,它可以在出现问题时快速做出响应并能就应用程序所需的内容明确交流目标。

Richard Campbell 是 Microsoft 的一位区域总监,ASP.NET 方面的 MVP,他还是《.NET Rocks, the Internet Audio Talkshow for .NET Developers》(转到 dotnetrocks.com)的合著者。多年来他一直为各公司提供有关 ASP.NET 性能和扩展方面的咨询服务,他还是 Strangeloop Networks 的共同创始人之一。

© 2008 Microsoft Corporation 和 CMP Media, LLC。保留所有权利;未经允许不得复制本文的部分或全部内容。