zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

ASP指南

ASP 指南
2023-06-13 09:13:41 时间

简介

“ActiveServerPage(ASP)”应用程序的成功常常取决于对体系结构和设计这两方面的取舍。考虑到ASP技术的范围之广和当前应用程序固有的复杂性,这种取舍是非常困难的。本文中,我将为您提供一些特定的指导方针,以助您成功开发基于ASP的应用程序。

从过去成功的开发模式经验中,我们总结出以下原则。

我已将指导方针整理成一组开发原则。在评估解决方案和技术时,可以应用以下原则帮助您做出决策。以下原则是我长期以来从成功的开发模式所得的经验积累。

原则1:采用标准方法

建立命名约定并使目录结构标准化,可以帮助您大大提高ASP应用程序的可读性和可维护性。虽然目前尚无ASP应用程序的正式标准,许多开发人员还是建立了一些通用方式。在此,我将与您共享一些更为通用的方式。

因为ASP技术依靠脚本引擎进行工作,而且脚本具有类型不严密的天性,命名约定也很模糊。在类型非常严密的语言中,变量将按照它的实际类型进行声明。在使用ASP技术时,通常按照处理变量的方式(而不是其实际数据类型)在ASP代码中声明变量。例如,在使用“VisualBasic(R)ScriptingEdition(VBScript)”时,尽管所有的VBScript变量都是Variant,你还是会将成功标志声明为bSuccess(b代表布尔型),而不是vSuccess(v代表Variant)。

下表是一些通行的命名约定。

变量前缀:

前缀 使用的变量 变量示例 borbln Boolean bSuccess corcur Currency cAmount dordbl Double dblQuantity dtordat DateandTime dtDate forflt Float fRatio lorlng Long lMilliseconds iorint Integer iCounter?? sorstr String sName aorarr Array aUsers() oorobj COMObject oPipeline

数据库对象的变量前缀:

前缀 使用的变量 变量示例 cnn Connection cnnPubs rst Recordset rstAuthors cmd Command cmdEmployee fld Field fldLastName

范围及前缀的用法:

前缀 说明 g_ 创建于Global.asa。 m_ 对于ASP页或在Include文件中是局部的。 (没有前缀) 非静态变量,对于过程来说前缀是局部的


KnowledgeBase(KB)中的一篇文章“Q110264INFO:MicrosoftConsultingServicesNamingConventionsforVisualBasic”(英文)对命名约定提供了真知灼见。

尽可能采用目录结构为您的各个应用程序部件提供始终如一的位置。您应用程序的实际目录结构当然由您自己决定,但通常是将图像、文档、include文件和组件分别放置在单独的目录中。以下是简单ASP应用程序目录结构示例。

目录结构示例:

\SimpleAspApp \Docs \Images \Includes

一个好的目录结构允许您有选择地应用NTFS权限。您还可以从ASP应用程序内部使用相对路径。例如,可以使用以下代码,从位于SimpleAspApp目录的default.asp页,引用Includes目录中的include文件top.asp:

./includes/top.asp

注意我的include文件的扩展名是.asp,而不是.inc。这样做是出于安全方面的考虑,而且使用.asp扩展名(而不是.inc),还能够在VisualInterDev(R)中使用彩色编码。

有关结构化ASP应用程序的其他一些提示和技巧,请参阅文章“ASPConventions”(英文)。

原则2:设计为在服务下运行

ASP将在服务下运行。设计ASP应用程序时,您马上会面临在桌面应用程序中不会遇到的安全环境和线程问题。在桌面环境中,通常只处理作为交互式用户运行的单线程执行,而且有权访问当前的桌面系统。在“Internet信息服务(IIS)”中,模拟不同用户环境的多个客户机线程调用您的应用程序,而且您的应用程序被限于“系统”桌面。

这对您来说意味着什么?请学习IIS的安全模式。还要提醒您:仅因为某些东西能在VisualBasicIDE下能够正常运行,并不意味着它就能在ASP技术中安全运行。VisualBasicIDE并没有准确地模拟运行时环境。常见的设计错误包括:在ASP技术中使用需要用户界面的.OCX控件,使用对线程来说不安全的组件,和使用要求特殊的用户上下文的组件。要避免的一个最简单的问题,就是从应用程序中试图访问HKEY_CURRENT_USER(HKCU)注册表项(例如,不要调用VisualBasic的GetSettingSaveSetting函数,它们都依赖于HKCU)。同样,不要出现需要用户进行人机交互的消息框或其他对话框。

以下文章是有关ASP技术中的安全和验证问题的相当不错的入门读物:

  • “AuthenticationandSecurityforInternetDevelopers”(英文)
  • “Q172925INFO:SecurityIssueswithObjectsinASPandISAPIExtensions”(英文)

原则3:封装商务逻辑

ASP技术通过生成HTML输出提供了表示服务。简而言之,它会生成用户界面。您需要将商务逻辑从ASP表示脚本中分隔开来。即使您不使用COM组件将商务逻辑从ASP代码中分隔开来,至少也要将商务逻辑分隔到函数和include文件中,以提高可维护性、可读性和可重用性。在需要排除故障和隔离问题时,您还能体会模块化设计方法的好处。

调用脚本内部调用函数和方法,可避免代码乱作一团,并能在ASP应用程序中添加结构。下面举例说明从ASP代码中,将逻辑分离到方法调用中:

lt;%Main() MyBizMethod() ... SubMain() GetData() DisplayData() EndSub %>

在使用包含ASP功能的技术时,可以应用这一原则。下面举一个使用VisualBasicWebClass时的例子,说明如何使用这一原则:

  • 因为WebClass本身引用ASP代码生成HTML,所以您不要将商务逻辑直接置于WebClass内。因为这是您的表示层,不在MTS/COM+下直接运行WebClass。
  • 从WebClass,可以调用能运行在MTS/COM+中的单独商务组件。
  • 您可以决定创建自己的、具有对ASP引用的COM组件,而不是依赖于WebClass框架结构和额外的WebClass运行时开销—您也可以使用ASP脚本直接将商务组件自动化。

原则4:尽晚获取资源,尽早释放资源

常见的问题是,从桌面系统到服务器的过渡。许多具有桌面系统背景的开发人员从来没有为服务器的一些问题和资源共享担心过。在传统的桌面应用程序中,连接到服务器是个耗时的过程。为了改善用户的体验,通常采用尽早获取资源和推迟释放资源的方法。例如,许多应用程序会在它的整个运行时间内始终连接着数据库。

这种方式在传统的桌面应用程序中能够正常工作其原因是用户数量非常明确,容易加以控制,并且后端与前端紧密连接。然而,对于当前的Web应用程序,这种方式已经不可行了,其原因是有限的服务器资源将面对越来越多的用户。为了使您的应用程序能够应付用户的增加,您需要尽晚获取资源,尽早释放资源。

共用有助于增加这一方式的有效性。通过共用,多个用户能够共享资源,而且等待时间最少,对服务器的影响也最小。例如,在处理数据库时,ODBC连接共用和OLEDB资源共用可以实现从共用池中选择连接,最大程度地减少连接数据库的开销。

有关共用ADO的详细信息,请参阅“PoolinginMicrosoftDataAccessComponents”(英文)。

原则5:使用数据库维护复杂的状态

尽管HTTP协议是无状态的,ASP开发人员还是会经常使用ASP功能内置的状态保持机制。例如,使用ASP技术内置的Application对象,开发人员所保存的资源能够为应用程序的所有用户共享。通过使用ASP内置的Session对象,开发人员只为单个用户保存资源。

尽管听起来在ASP技术的Session对象中保存信息是一个非常方便的保持状态的方式,然而这一方式付出的代价太大,而且它也可能成为对可伸缩性的最大的限制因素之一。应用程序的可伸缩性本质上是随着用户数目的增长能够继续保持其性能的能力。而对于每一用户,在会话超时或被放弃之前,Session对象都会消耗服务器的资源。会话还会将您捆绑到一台服务器上,从而限制您利用Web集群的功能。请尽可能不要使用ASPSession对象进行状态管理。如果您完全没有使用会话,您就可以禁用Web应用程序的Session状态(请参阅IIS文档)。否则,您可以使用下述语句,针对每一页禁用Session状态:

<%@ENABLESESSIONSTATE=False%>

对于一些简单的数据,您可以使用QueryStringcookie或隐藏的窗体域保持ASP请求间的状态。然后,对于更为复杂的信息,通常推荐您使用数据库。一般所采用的方式是生成某一特有的标识符,然后发送到每一个发出请求的客户机,并保存为隐藏的窗体域。在随后的请求中,这一特有的标识符被用于在数据库中查找与该用户相关的状态信息。这一方式提供了更高的可伸缩性和更为简洁明了的代码。

有关使用QueryStringcookie和隐藏的窗体域的详细信息,请参阅“Q175167HOWTO:PersistingValuesWithoutSessions”(英文)。

原则6:使用Server.CreateObject创建对象

在创建ASP技术的对象时,您可以选择<OBJECT>标记、Server.CreateObjectCreateObject三种方式。每项技术的行为略有不同。尽管在IIS4.0中,使用<OBJECT>标记或CreateObjectServer.CreateObject略具性能优势,我们一般还是推荐使用Server.CreateObject,以便于ASP应用程序认知您的对象。(注意在IIS5.0中,前两项与Server.CreateObject相比,已经没有性能优势。)

<OBJECT>标记仅在调用第一个方法时才会创建组件,因此能够节省资源。Server.CreateObject使用ASP技术内置的Server对象创建组件。实质上,它只是执行了CoCreateInstance,但是ASP却能够认知这一对象。同时,还将调用ASP技术的传统的OnStartPageOnEndPage。(注意最好在IIS4.0或者更高版本中使用ObjectContext)。如果您只是使用CreateObject,您将越过ASP技术而直接使用Scripting引擎。

以下是一个可能出现的例外情况:当您通过防火墙进行调用时,您可能需要调用CreateObject而不是Server.CreateObject详细信息,请参阅“Q193230-PRB:Server.CreateObjectFailswhenObjectisBehindFirewall”(英文)

原则7:提供丰富的疑难解答信息

确保在您所有的ASP应用程序中都包含了错误处理过程。而且,确保您提供了有用的诊断信息。我还没有碰到有哪个人抱怨错误信息太具有说明性了。请确保在错误日志中包含以下信息:

  • 用户上下文(如果您正在使用组件,您可以调用GetUserName
  • 线程ID(在组件中,可以调用GetCurrentThreadId)<
  • 时间
  • 完整的错误信息(包括编号、来源和说明)
  • 参数值

因为将在ASP下运行,您可能希望将这些信息写到文件或NT的事件日志。您还可以创建记录关键的应用程序事件的应用程序事件日志,以备诊断应用程序错误时使用。

以下文章提供了有关错误处理技术的详细信息:

  • “BulletproofingYourASPComponents”(英文),CharlesAlexander著
  • “Fitch&MatherStocks:WebApplicationDesign”(英文)
  • “HandlingandAvoidingWebPageErrors,Part1:TheBasics”(英文)
  • “HandlingandAvoidingWebPageErrors,Part2:Run-TimeErrors”(英文)
  • “HandlingandAvoidingWebPageErrors,Part3:AnOunceofPrevention”(英文)

原则8:测试性能、可伸缩性和可靠性

浏览器并不是准确的测试方式,它只能向您展示应用程序可能的用途。请针对您的应用程序设置特定的性能目标,并使用WebApplicationStressTool等负载工具进行压力测试。您需要自己决定您的环境所能接受的条件,以下是一些帮助您启动测试过程的通用指导方针:

  • 通过测试ASP每秒钟的请求数对性能进行测试,并建立一个最小的阈值。一般情况下,不执行数据库访问的简单ASP页每秒钟至少应返回30页。调用组件或访问数据库的页每秒钟至少返回25页。
  • 向应用程序不停地追加用户,直到每秒钟的请求数低于预先设置的阈值,用这种方式测试可伸缩性。
  • 从Web集群中移去机器,并检查错误和故障情况,以便测试可靠性。

将测试环境与实际运行的环境相匹配,甚至防火墙也不例外。这听起来代价很高,但我曾经听说过开发人员因为没有考虑到防火墙,而丢失了工作。

有关使用WebApplicationStressTool测试ASP应用程序的详细信息,请参阅“ICan"tStressItEnough--LoadTestYourASPApplication”(英文)。

原则9:增加隔离性

使用隔离功能保护您的应用程序过程能够极大地增强服务器的稳定性。谈到Internet应用程序,是否使用隔离功能的后果可能会有巨大的差别:一个是应用程序崩溃,一个是服务器当机。保护主IIS进程(InetInfo.exe)通常会排在优先级列表的较高位置。在您使用组件时,这一点尤为突出。

通常所采用的保护主ISS进程的技术是使Web应用程序运行在各自的内存空间中。在InternetServicesManager中,您可以针对每一个Web设置这一选项。虽然因对进程进行编组而开销的系统资源会对性能有些微的影响,但对应用程序所起的保护作用值得付出这一代价。在IIS4.0下,您可以采用进程内(in-process)和进程外(out-of-process,OOP)两种方式运行应用程序。OOP应用程序会运行在新的Mtx.exe实例中。在IIS5.0下,您还能使用其他的隔离选项。可以将隔离级别设置为“低”(对Inetinfo.exe来说是进程内应用程序)、“中”(DllHost.exe共享实例)或“高”(Dllhost.exe的非共享实例)。

除了将Web应用程序隔离在它们自己的内存空间中之外,您可能还希望隔离不信任的组件。不信任的组件通常是在实际环境中没有通过测试时间的考验的组件。您可以在Server包中运行这些组件,这样它们会运行在新的Dllhost.exe实例中。

一般而言,如果要在性能和保护措施之间采取中庸之道,方式如下:在“高”隔离状态运行Web应用程序,在库包中运行组件。这种方式最大限度地减少了编组开支,同时在进程之间提供了最强的保护作用。

详细信息,请参阅文章“ServerReliabilityThroughProcessIsolation”(英文)。

原则10:不要滥用线程共用组

在IIS4.0下,针对每个受MTS管理的处理器,ASP的默认共用组是10个线程。在IIS5.0中,默认值是20。这就意味着每一线程都是一份潜在的宝贵资源,能够处理多个客户机请求。您同样需要避免调用会出现阻塞的方法,如进行大的数据库调用。如果您有要执行这种操作的工作,它将阻止ASP应用程序将响应快速返回到客户机,则请考虑使用队列功能。例如,在NT4.0中,可以使用MSMQ。在Windows2000中,可以使用QueuedComponents(排队组件)。

在会话中不要存储Single-threadedApartment(STA)组件,这种方式的一个共同缺陷是会填满会话范围中的VisualBasic对象。会将用户锁定到某一线程,与线程共用组的目的背道而驰。潜在的用户会被阻塞在其他用户的后面,等待创建他们组件的线程变得有效。您应该采用别的方式,设计能基于每一页进行创建和破坏的无状态组件。

快速提示:确保已在服务器上禁用了ASPScriptDebugging功能(使用InternetServicesManager)。如果启用了ASPScriptDebugging,则ASP的执行过程将被锁定到某一线程。

详细信息,请参阅以下文章:

  • “Q243544INFO:ComponentThreadingModelSummaryUnderActiveServerPage”(英文)
  • “Q191979PRB:VBComponentNotMarkedApartmentProducesASP0115Error”(英文)
  • “Q243548INFO:DesignGuidelinesforVBComponentsUnderASP”(英文)
  • “Q243543INFO:DoNotStoreSTAObjectsinSessionorApplication”(英文)
  • “TuningInternetInformationServerPerformance”(英文)

摘要

创建ASP应用程序需要相当宽广的知识面。ASP应用程序所面临的一个挑战是目前没有通用的规则(这也正是乐趣的一部分)。另外一个问题是许多开发人员接触Internet开发之前是从事桌面系统的开发工作。通过在您的ASP开发工作中应用上述规则,您有希望避免犯下代价巨大的错误,并能开发出相当不错的ASP应用程序。

J.D.Meier出生并成长于美国东海岸。听从HoraceGreeley的建议,他成为一名开发人员支持工程师,主要致力于包括MTS和ASP技术在内的服务器端组件以及WindowsDNA应用程序。