应用程序服务器Application Server
为什么要有应用程序服务器?
近十年来,基于Internet的应用正以前所未有的高速度向前发展,其中一个重要的方向就是基于Web的应用系统的发展。在此期间,随着技术的不断更新和应用的不断深入,Web应用系统的发展也经历了几个阶段性的跨越。
在Web发展的初期,人们通常使用Web服务器作为信息发布工具,它接收用户的HTTP请求,然后根据请求提供所对应的HTML文档,除了显示手段更为丰富的特点之外,HTML文档与普通静态文本并没有本质差别。
随后产生了动态页面和更多交互能力的需要,新的应用需要根据客户请求,从数据库中动态获取数据并予以显示。由此所产生的技术手段有CGI和Web服务器内置API等。这些手段在一定程度上满足了应用需求,但也都存在着各自的局限性:CGI效率低、速度较慢,而内置API开发困难,移植性差。
随着Web应用范围的扩大,基于商业应用的Web开始出现,人们需要Web服务器端提供更为复杂的和更为灵活的应用开发支持。JavaScript、VBScript等技术的运用,Web中对象和组件的应用使基于Web的商业程序开发得以迅速发展。但这种应用通常只适用于构建规模不大的商业系统,当商业系统进一步扩大时,其扩展性受到了限制,因为在Web服务器最初的设计目的中并不包括对大规模、高性能和高可靠性商业应用的支持。
应用程序服务器(Application Server)的产生正是为了突破这一瓶颈,应用程序服务器完全不同于Web服务器,是专门为基于大负荷高端处理的Web应用而设计的全新的运行环境,该环境能提供很高的可靠性,健壮的程序逻辑处理能力,能轻松地为成千上万甚至上百万用户提供服务。
另一方面,应用程序服务器的产生与软件体系结构的演变发展也是密切相关的。让我们简单回顾一下软件体系结构的发展历史。与最初的大型中央主机相适应,最初的软件结构体系也是Mainframe结构,该结构下客户、数据和程序被集中在主机上,通常只有少量的GUI界面,对远程数据库的访问比较困难。随着PC的广泛应用,该结构逐渐在应用中被淘汰。
在80年代中期出现了Client/Server分布式计算结构,应用程序的处理在客户(PC机)和服务器(Mainframe或Server)之间分担;请求通常被关系型数据库处理,PC机在接受到被处理的数据后实现显示和业务逻辑;系统支持模块化开发,通常有GUI界面。Client/Server结构因为其灵活性得到了极其广泛的应用。但对于大型软件系统而言,这种结构在系统的部署和扩展性方面还是存在着不足。
Internet的发展给传统应用软件的开发带来了深刻的影响。基于Internet和Web的软件和应用系统无疑需要更为开放和灵活的体系结构。随着越来越多的商业系统被搬上Internet,一种新的、更具生命力的体系结构被广泛采用,这就是为我们所知的"三层/多层计算"。
o客户层(client tier) 用户接口和用户请求的发出地,典型应用是网络浏览器和胖客户(如Java程序)
o服务器层(server tier) 典型应用是Web服务器和运行业务代码的应用程序服务器
o数据层(data tier) 典型应用是关系型数据库和其他后端(back-end)数据资源, 如Oracle和SAP、 R/3等
三层体系结构中,客户(请求信息)、程序(处理请求)和数据(被操作)被物理地隔离。三层结构是个更灵活的体系结构,它把显示逻辑从业务逻辑中分离出来,这就意味着业务代码是独立的,可以不关心怎样显示和在哪里显示。业务逻辑层现在处于中间层,不需要关心由哪种类型的客户来显示数据,也可以与后端系统保持相对独立性,有利于系统扩展。三层结构具有更好的移植性,可以跨不同类型的平台工作,允许用户请求在多个服务器间进行负载平衡。三层结构中安全性也更易于实现,因为应用程序已经同客户隔离。
应用程序服务器是什么?
应用程序服务器是三层/多层体系结构的组成部分,应用程序服务器位于中间层。应用程序服务器运行于浏览器和数据资源之间,一个简单的实例是,顾客从浏览器中输入一个定单,web服务器将该请求发送给应用程序服务器,由应用程序服务器执行处理逻辑,并且获取或更新后端用户数据。
在企业级应用中,应用程序服务器是位于企业数据(以及其他企业遗留系统)和访问企业数据的客户之间的中间件,它提供了业务代码的存放和运行的环境。它从物理上把业务逻辑(Business logic)同客户端和数据资源分离开来。应用程序服务器可使一个商业系统得以快速简便的开发和部署,也可以适应商业系统的用户增加而无需重构系统,这一切都是因为它处于一个相对独立的结构层。
在实际应用中,一个企业系统可以由多个应用程序服务器、多个Web服务器和多个数据库服务器组成,应用程序代码可以分布在这多个应用程序服务器上。
应用程序服务器是企业级web应用的必经之路,新的企业级应用需要关键性应用能对不断增加的用户数量保持持续可用,此外企业应用还需要高的安全性和可靠性,无论访问系统的用户数量发生变化,还是系统数据资源发生变化,应用程序服务器都应始终保持运行。在应用程序服务器之前,Web应用程序通常运行在Web服务器中,但Web服务器最初只是被设计用来提供Web页面相关服务的,因此开发/运行Web应用程序是缓慢而复杂的。而应用程序服务器的强大功能则能够为企业级应用系统的开发和部署提供有力的保证。
一个对应用程序服务器的定义如下:采用具有分布式计算能力的集成结构、支持瘦客户机的软件服务器产品。应用程序服务器的基本用途包括:管理客户会话、管理业务逻辑、管理与后端计算资源(包括数据、事务和内容)的连接。
上述定义的涵盖范围是应用程序服务器本身,我们认为实际上应用程序服务器还应该包括其开发环境。每一个应用程序服务器产品都有自己的API。为了充分利用应用程序服务器所提供的功能,开发人员必须学会用这些API编程。服务器的API对实用系统的开发至关重要,掌握API方法和它们提供的功能需要花一定的学习时间。
越来越多地,应用程序服务器采用诸如COM、CORBA、Enterprise JavaBeans(EJB)和Java Servlets等标准化技术(其中CORBA和EJB更为常用),上述标准化技术的采用使开发变得更加容易,因为它们为通用服务器管理功能提供了标准化API,遵循标准保证了当更改应用程序服务器时原有组件可移植。
但另一方面,每个应用程序服务器产品提供商都会对标准加以扩展,增加自身特色以赢得竞争优势。这就导致了Web世界中的大量争论,对标准的兼容成为热点问题。
一个很重要的问题摆在Web应用系统开发者的面前:我需要应用程序服务器吗?
答案通常是需要,尤其当你要构建一个企业级系统时。即使你没有可扩展性的需求,你也能从应用程序服务器中得到很多其他收益。基于Web的开发已经迅速从数据发布、少维护量的应用转向完整、复杂的商业应用。应用程序服务器可以简化新的商业交互程序的开发;随着应用系统规模的不断扩大,逻辑重用和团队开发变得越来越重要。此外,由于应用程序需要获得组织内更多的数据资源,对数据访问的集中管理和集中安全也越来越重要。应用程序服务器通过对象和组件技术为此提供了很好的解决方案。
如果你需要构建同时支持HTML客户和胖客户的应用系统,你肯定需要应用程序服务器。作为三层客户/服务器结构你当然不能缺少中间层!你同样可以利用应用程序服务器的业务逻辑和数据访问组件。
应用程序服务器必须从某个地方获得它所需要的组件(业务逻辑、数据访问对象、HTML生成组件等),这些组件都要被加载到服务器中。组件的开发和加载的容易与否取决于开发环境,有些应用程序服务器提供商依靠第三方IDE和工具来为服务器提供组件,另一些供应商则把开发工具与服务器集成在一起。你可以根据具体需要来作出选择。 应用程序服务器可以分为以下几大种类:
纯运行Web应用服务器(Pure-Play Web Application Server)
这类服务器是与开发工具独立的,支持某些种类的标准组件模型如CORBA或EJB。这类服务器产品供应商把主要精力放在支持扩展性和与不同数据资源的连接上。代表性产品有Netscape NAS,IBM WebSphere,WebLogic Tengah和Novera jBussiness。这些服务器倾向于以Java为中心,帮助开发者使用EJB组件和Servlets来构建系统。你可以使用喜欢的Java IDE来创建组件并加载到服务器中。 开发及部署服务器(Develop-and-Deploy Server)
开发及部署服务器将开发环境与应用程序服务器紧密集成。它们允许开发者迅速开发应用系统并立刻部署,它们的侧重点主要放在复杂环境中高度交互开发的能力。代表性产品之一是SilverStream Application Server和Sun NetDynamics。
来自Client/Server供应商的应用服务器(Application Servers from Client/Server Vendors)
另外一类产品由目前比较流行的工具供应商提供,这类服务器对习惯于传统的Client/Server方式的开发人员比较有吸引力。比如Microsoft MTS和Sybase Enterprise Application Server。MTS采用COM组件模型(并没有太多应用程序服务器采用COM作为组件标准),而Enterprise Application Server 3.0 几乎能容纳所有组件(包括PowerBuilder组件)。这类服务器最主要的好处在于对原有代码的重用。
应用程序服务器到底能做什么
所有应用程序服务器有其共有的基本特性,包括连接管理,状态和会话管理,业务逻辑集中和数据库连接等。很显然,应用程序服务器必须支持允许客户连接的有关协议,必须有验证用户的安全机制。服务器进程的主要工作是管理客户连接,以及将到来的客户请求重定向到不同的后端资源。
安全服务(Security Services)
为了获得资源访问权,客户必须通过服务器的认证,因此服务器必须要有验证用户的安全设施。大多数应用程序服务器提供增加用户/用户组的机制和对组件的访问控制。此外,越来越多的应用程序服务器提供对安全服务的验证(如操作系统,LDAP等),更高级的安全通过用户主机上X.509数字认证的使用来实现。一旦用户身份被验证,服务器将允许或禁止他对组件的访问和所管理的数据连接。
状态和会话管理(State and Session Management)
服务器必须在同一用户会话过程中多次请求之间维护有关的状态数据。从扩展性方面考虑,运行在服务器上的组件应避免使用实例变量。在应用程序服务器环境中,服务器必须通过会话对象来保持用户数据。会话对象(Session Object)的唯一功能就是保存服务器端的数据,它可以简化复杂应用程序的开发,因为它可以使你不必在程序中编写有关使用cookies和隐藏字段来回传递状态的代码。同时它也使那些存在安全风险的数据远离浏览器端,增加系统安全性保证。一般情况下,在浏览器和服务器间来回传递的唯一信息只是会话ID。
对于胖客户机连接(Java,VB,PowerBuilder等),用户进程与应用程序服务器保持持久连接,客户与服务器端的持久性对象间随时可能发生数据传递。由于服务器上组件变得更加状态化,更加绑定于某个特定用户,服务器所能处理的用户数将减少。因此开发人员更愿意采用如下方法:从服务器端请求数据,断开与特定对象的连接,在客户端本地处理数据,然后把数据变化发送给服务器以求确认并前推给数据库。在这种情况下会话对象变得不太重要,但它仍然提供了一种手段,使得服务器端的对象之间可以不经客户而直接传递数据。
负载平衡和失败恢复(Load Banlancing and Fail-Over)
所有的应用程序服务器都提供某种类型的负载平衡和失败恢复机制。负载平衡意味着一组服务器可以被集中成为一个服务器集群(cluster/farm)。发往服务器的请求被一个分配器(dispatcher)处理以便将请求发给最空闲的服务器,此后客户将直接与那台服务器通信。负载平衡机制为系统提供了很好的扩展性,随着用户负载的增加,更多的服务器主机可以被加入到服务器集群中。
失败恢复机制提供容错性。如果集群内某台主机失效停机,新的请求将被重新路由给其他某台服务器。简单的失败恢复不能解决所有问题,如果用户在某项任务过程中服务器停机,负载平衡机制将会发现这个问题并将该用户重新转配给其他服务器,但是该用户的状态和会话数据将对新服务器不再可用。正因为这个缺陷,有的应用程序服务器提供会话级失败恢复,状态和会话数据将被复制给集群内其他服务器或是被存储在永久性媒介(如数据库)中,使用户数据对每个服务器总是保持可用。 业务和处理逻辑(Business and Processing Logic)
在应用程序服务器的核心部分集中容纳了业务逻辑(即访问,生成数据和执行处理的代码)。与应用程序相关的业务逻辑可以由可重用组件组成,而不需要每个开发者自己开发。一旦组件被创建,就可以被载入到应用程序服务器中,分配适当的安全设定,然后就可以运行。大多数应用程序服务器提供机制用于指定组件的持久性,事务处理设定和线程设定等。 胖客户访问服务器组件(Rich-Client Access to Server Components)
胖客户可以直接访问服务器端组件。例如Java applet可以请求服务器实例化一个组件,然后就可以调用其方法。通常的执行顺序是:连接服务器,调用方法获得数据结果集,断开连接,显示数据给用户并允许对数据操作,执行本地数据更新,连接服务器,发送数据更新给服务器,执行服务器上数据更新,最后将数据存入数据库。
HTML生成
纯的瘦客户程序不能直接与服务器端组件通信,没有办法用客户浏览器的HTML或ECMA脚本交换结果集。这意味着服务器端需要另一个组件来生成和处理HTML。应用程序服务器必须解码(decode)一个URL,来决定执行哪一个组件。该组件访问数据库或其他组件,获得结果集,将结果集包装为HTML(或XML),再将其返回给浏览器。应用程序服务器上的HTML生成组件变成了业务逻辑组件的客户。
一旦页面被返回给浏览器,我们期待用户更改数据并提交回应用程序服务器。返回给服务器的数据可以作为URL参数(GET),通过表单字段(POST),或者通过cookie。服务器从HTTP请求中获取数据,使其为服务器端被调用的组件使用。
数据访问
应用程序服务器提供机制,用于增加和管理与关系型数据库(如Oracle,DB2)的连接。一旦数据源被加入,组件可以对其作调用,发布SQL请求。现在越来越多的应用程序服务器也允许访问非关系型数据源(如CICS)。对关系型数据的访问已经相当标准化(JDBC、ODBC等),而对非关系型数据的访问接口还是由每个应用程序服务器自己实现。第三方供应商也为不同的应用程序服务器提供接口产品,使其易于访问其他数据源(SAP,PeopleSoft,Notes和CICS/MQSeries等)。通常的做法是创建某种类型的对象或组件来包裹数据源,并使其功能可以为其他组件所使用。通过将非关系型数据源封装在对象中,前端开发者就可以提供对流数据的访问而不需要知道访问具体是如何实现的。 事务管理(Transaction Management)
Web开发人员和应用程序开发人员过去习惯于自己完成数据库事务管理。无论采用什么编程语言,几乎每个人都使用SQL访问数据,然后是确认或者回滚。而在应用程序服务器环境中,事务是由服务器唯一管理的。开发人员编写发布SQL请求的代码和通知服务器该逻辑是否成功的代码。如果该调用序列中任何组件执行失败,服务器将执行回滚;否则服务器执行确认。服务器提供不同级别的事务控制,例如它可以使某个特定的组件有其独立的事务。 连接池(Connection Pooling)
当页面被提交,数据被更新时,服务器必须连接数据库以完成工作。如果用户每次提交页面时都要执行数据库连接和断开,系统的性能和扩展性就会变得很差,因为在一个事务周期中建立到数据库的连接是一个开销相当大的操作。一个解决方案是当用户登录时建立连接,而当用户离开或超时时断开连接。但这个方案显然缺乏可扩展性,如果5000个用户同时登录,那么就需要5000个数据库连接。
应用程序服务器不为每一个用户保持单独连接。实际上,它维护了一个连接池,供所有服务器端组件共享。如果用户需要更新数据,相应组件就会请求服务器从连接池中分配一个可用连接,当所有的更新被完成后,组件负责通知服务器是否所有操作都成功。当一个事务结束后,连接被立刻释放。 线程池和实例池(Thread Pooling and Instance Pooling)
高端的应用程序服务器还提供线程池和实例池。因为对于线程或者组件实例而言,开销最大的操作来自创建和实例化过程。线程池和实例池可以提供更好的性能,线程和组件实例可以立刻被服务器所使用。但如果组件是有状态的,或者线程不能被快速释放,线程池和实例池机制将不能发挥其优点。
第二章 NAS:性能、扩展性和可靠性
Netscape Application Server (NAS)所宣称的高性能、高扩展性和高可靠性的背后是什么?象大多数Web程序开发员一样,你可能非常熟悉Web服务器怎样工作,它能实现什么,不能实现什么;但你可能并不了解一个应用程序服务器的内部结构,特别是NAS,为什么它能为复杂的Web应用程序提供更快、更可靠的运行环境?在这里,复杂的Web应用程序通常要提供动态用户界面,访问多个不同的数据库,实现与企业遗留系统的交互等。
下面的内容将帮助你理解为什么NAS是开发Web程序的更好选择。
不同的体系结构,不同的目标
我们无意于强调NAS比Netscape Enterprise Server(Netscape的Web服务器)更好,它们是为不同的目标而设计的。在Web发展的早期,人们主要用它来发布信息,因此开发者只对如何使用HTTP协议提供HTML文档感兴趣, Web服务器(如Netscape Enterprise Server)就是为此目的而设计,它为相对较轻的应用代码提供通用运行环境,主要通过返回HTML页面来响应用户HTTP请求;在上述前提下,它工作得很好,但随着应用不断深入,人们需要开发更为复杂的Web应用程序,为此,不同的在Web服务器上开发Web应用的方法和访问数据库的方法被加入,但这种增强仅仅是功能的增加而不是体系结构的优化,所采用的技术手段如Server端插件、语言翻译(Perl等)也不能说真正实现了相对于Web环境的本地化处理。
不同于任何Web服务器,甚至是其他应用程序服务器,NAS 是专门为基于高端处理的Web应用而设计的。1995年, Keng Lim 提出了一个全新的概念:有朝一日,Web应用程序将需要一个新的运行环境,该环境能提供很高的可靠性,健壮的程序逻辑处理,能轻松地为成千上万甚至上百万用户提供服务。他的概念变成了Kiva Enterprise Server产品,该产品于1997年被Netscape收购并集成进NAS,因此可以说,NAS从体系结构上就专注于提供大负载、高可靠性的服务,可以满足接近于无限的用户数增长需求。
这就是NAS和Web服务器在定位上的区别,下面我们再就更细的技术层面来论述这个问题。
WEB 服务器和CGI: 访问数据库
Web服务器工程师很早就意识到通过Web来完成数据处理和显示的重要意义。最早期的处理方法是通过通用网关接口(CGI),它们可以用不同的编程语言实现,包括C/C++ 语言和Unix 脚本语言(如Perl和tcl)
图1显示了CGI脚本是如何工作的,一个请求被从Web浏览器发出,(例如:http://server.domain.com/cgi-bin/myCGI.pl),该请求实际指明的是一个服务器端程序而不是一个标准Web页面,Web服务器执行被请求的应用程序(myCGI.pl) ,随后将输出结果返回给Web浏览器。因此,当你发出一个CGI请求时,你不是在请求HTML文档,你实际上是在请求服务器端程序的输出。
图1 通过CGI脚本获取数据
这种方法的最大局限是当每次CGI脚本被激活时服务器必须启动一个新的进程,处理过程结束后进程随之结束。换句话说,CGI过程不能在本次激活和下一次激活间保持,这就造成了高的进程开销,限制了给定时间内可以运行的CGI脚本数目,降低了Web服务器的处理速度(有一种被成为"快速CGI"的解决方案将CGI脚本置于内存中,用以提高CGI应用程序的性能)
CGI还有其他一些影响性能的限制,服务器必须为每个Perl CGI脚本运行Perl解释器, C/C++ CGI脚本比Perl脚本运行速度快但是更复杂,需要更多的编程技巧。在对数据库操作时,开发者需要使用与数据库相关的内嵌SQL或函数库,一旦更换数据库,需要大量代码改写。此外, CGI脚本在每次执行数据库操作时都要执行数据库连接和断开这两个费时操作。CGI的另一个缺点生成Web页面的HTML代码与实际程序代码(C/C++, Perl等)紧密耦合,改变页面外观可能涉及对CGI程序的修改。
尽管如此,CGI脚本在工作组级(少量用户)的情况下还在被广泛地使用,因为它相对简单,易于开发,能够在不同的Web服务器间移动(虽然很少有这么做的必要)。对于那些对性能和可维护性要求不高的网站而言,对于简单、一次性的系统任务而言,CGI还是一个理想的方案;而对于数据库驱动的Web应用程序和必须长时间维护的Web站点而言,CGI脚本是一个糟糕的解决方案。.
WEB服务器和服务器端JavaScript: 改善应用程序性能
在基于Web服务器的Web应用方面还是有明显优于CGI的技术存在,服务器端JavaScript(SSJS)就是其中之一,它被Netscape于1996年提出,随后很快被Microsoft仿制。它被认为是优良的工作组级和部门级解决方案。
SSJS运行环境引擎(NSAPI插件)在Web服务器内运行(参见图2),因此它是持续可用的;因为Web服务器无需在每次使用SSJS时实例化一个新进程(如同CGI所做的一样),它能更快、更有效地处理请求。
CGI脚本把HTML代码包含在程序逻辑内,而SSJS程序用JavaScript语言编写,并被存放在HTML页面(类似于客户端JavaScript的实现),因此构成应用程序的Web页面可以被HTML开发者而不是应用程序开发者修改。
基于CGI的Web程序通常由两种语言构成(前端是客户端JavaScript,后端是Perl或C/C++),基于SSJS的Web程序仅采用JavaScript语言,在程序开发上更具一致性。此外,
因为SSJS是客户端JavaScript核心语言的超集,开发者可以在客户端程序和服务器端程序间共享代码, 同时JavaScript是相当流行而且简单的编程语言,寻找JavaScript程序员比Perl或C/C++程序员更为容易。
在数据库操作方面,SSJS程序比CGI脚本更友好,执行速度更快。SSJS程序不需要在处理每次请求时都连接和断开数据库,这是因为SSJS对象具有与Web服务器同样长的生命周期,DBPool对象可以永久保持与数据库的连接,也能同时建立多个与不同数据库系统的连接(SSJS支持访问Oracle, Informix, Sybase, DB2以及所有的ODBC数据库),在处理并发访问方面效率更高。
SSJS允许你最大限度发挥三层体系结构(three-tier architecture)的优点。在传统的两层客户/服务器结构(two-tier client-server architecture)下,客户直接连接到数据库,中间不需要通过Web服务器或者其他服务器。这在数据库处理和许可方面都是比较昂贵的,每个客户都需要连接到数据库,都需要访问数据库的许可。而在三层结构中,多个客户可以访问一个Web服务器,而由后者维护与数据库的共享连接,因此只要更少的数据库许可和数据库处理开销。
图3比较了两层结构和三层结构,可以看到在两层结构中,每个客户都有一个到数据库的连接,这意味着当用户在读取或输入数据时,数据库连接实际处于空闲状态。而三层结构在数据库连接的使用上效率更高,由于数据库连接被共享,因此可以用更少的数据库连接支持更多的用户。数据库连接被更高效地利用,通过共享连接的数据流相对更连续。另外,数据库的连接可以一直保持直到应用程序结束,因为用户是登录到位于服务器的应用程序上而不是数据库上。
SSJS还提供状态管理和会话管理功能,上述功能已经成为SSJS运行环境的一部分。
会话管理用于:
确定用户是否已经登录
监视用户活动
提供用户活动记录
存储同一个应用程序内不同页面上需要使用的用户信息
跟踪多个HTTP请求之间需要保存的信息 等
状态管理用于监视应用程序使用情况,检测应用程序正在做什么、多少用户正在使用它等,以利于信息和资源在用户间共享。
SSJS为状态管理和会话管理定义了四个对象:
Server对象:用于在应用程序间共享信息
Project对象:主要用于状态管理
Client对象: 用于会话管理
Request对象:用于提供基于页面的信息,便于访问被传递给页面的数据
这些对象始终保持运行和对应用程序可用,开发者只是需要决定会话信息是存储在客户端(如果服务器停机,重启后不会丢失任何用户会话信息),还是存储在服务器端(能支持并未激活客户端cookies的浏览器)
SSJS比CGI(它是无状态的)有所改善,但还不是最理想的,因为状态和会话信息还不能在服务器之间共享。这是难于将SSJS扩展至工作组和部门范围以外的最大原因。如果你在SSJS程序中没有使用状态/会话信息,你可以很好地将系统扩展至工作组以外;但如果使用了,你就有可能碰到麻烦:如果你的系统是一个多台服务器的环境,如果其中一台服务器在处理过程中停机,用户可能丢失定单或数据库信息,他们不得不回到最初的地方重新开始,即使在这过程中他们被自动重定向到另一台服务器上。
正如我们所知道的,SSJS不是一个针对企业级关键应用的真正理想的方案。在企业级关键应用中,许多用户和应用程序(包括相关的状态和会话信息)必须全天候保持正常运行,而Web服务器毕竟不是专门设计用来处理数据库访问、分布式状态和会话管理、关键性任务处理的,Web服务器主要还是处理Web页面访问,通过插件它只能提供有限的应用程序方面的功能。
NAS: 可扩展的应用程序服务
NAS的出现极大改善了这个局面,它可以在同一服务器簇(cluster)内多台服务器间共享状态和会话管理。一个服务器簇由两台或多台主机组成,一旦一台主机停机,其余主机可立刻顶替,因为状态和会话信息是共享的,不会出现事务丢失。
NAS的设计出发点是提供应用程序服务,对于给定应用程序,不用考虑用户数量和并发请求数量的影响。如果用户群数量增加,只需要加入另外的应用程序服务器来处理负载,而应用程序无需作任何修改。在一个服务器簇内可以增加任何数量的服务器主机来支持给定应用程序。例如,香港电信的customer care and billing application支持超过200,000用户;2个月内开发完成的E*Trade's Mutual Fund application支持275,000 用户; 4个月开发完成的ISN's First Auction site 及其"flash" auctions支持8,000以上的并发用户。
NAS程序由HTML页面和应用程序逻辑(AppLogic)模块组成,如图4、图5所示,请求被Web服务器处理,如果关系到应用程序,请求就被转发到应用程序服务器处理。在应用程序服务器内部,请求被KXS进程(Kiva executive)接收,再转发给KCS进程(内部运行C/C++ AppLogic模块),或者KJS进程(内部运行Java AppLogic模块),每一个KCS和KJS进程维护特定数量的线程(由系统管理员配置),由这些线程负责执行AppLogic模块。这种方式提供了比CGI脚本和SSJS程序更快的响应速度,不会减慢Web服务器的速度。当一个AppLogic模块结束运行,结果被返回给Web服务器,最终返回给客户浏览器。
你可以增加任何数目的服务器,指定任何数目的KCS和KJS进程以及在每个进程内维护任何数目的线程,你可以很好地调优你的NAS环境,给你的应用程序带来最好的性能。这种细致调优无疑会导致更低的硬件需求和对存在的服务器的更高效利用,而这一点是CGI、SSJS或一般Web解决方案所无法提供的。
NAS是如何保证24*7(每天24小时,每周7天)的可用性的?图5从直观上显示了NAS内部是如何工作的。如果一个KCS或KJS进程意外终止,KXS进程将会重启进程。
如果KXS意外终止,则会有一个附加的管理进程(KAS)负责监视并重启KXS。NAS还会有其他的检查手段保证KAS始终运行。而当所有的进程都意外终止,那么同一服务器簇内的其他的NAS服务器就会接管服务,同时NAS会立即发送Email或传真通知系统管理员。
而对于CGI或SSJS,如果服务器意外停机,这个情况可能根本无法发觉,除非使用客户或雇员打电话来抱怨。NAS则使你早于用户发现意外情况,使你能及时修复存在的问题,免于整个应用系统崩溃。
NAS的存在可以使HTML与程序代码完全分离(CGI脚本的HTML嵌在程序代码中,SSJS稍好一些,程序代码嵌在HTML中),这个优点有利于应用程序的团队式开发,页面设计者只需专注于显示逻辑(HTML页面,Java GUI等),编程人员只需专注于业务逻辑(AppLogic模块和扩展),数据库管理人员只需专注于数据逻辑(SQL请求,视图,存储过程,函数等,以上内容被存放在请求文件中,与AppLogic模块分离)。工作组的每个成员都可以不受他人的干扰,集中、高效地完成本职工作。
若干建议
NAS适用于每个人吗?当然不是。有些站点规模很小,不需要支持大量的应用程序。而有的公司仅仅能支付得起一台主机和一个Web服务器的费用,当然不能期望他们使用NAS。我们只是希望他们了解NAS,知道当他们有进一步复杂应用的需要时,NAS是一个非常好的选择。
对于那些期望在未来(而不是现在)采用NAS以满足其站点流量增长和应用程序增强的用户,他们可能会思考现在能做什么?下面是我们的建议:
如果你使用CGI脚本,请考虑使用C/C++,以便将来在向NAS移植是不用全部重写。
如果你的Web开发人员不熟悉C/C++,Perl是一个不错的替代选择,但应注意,移植Perl应用程序到NAS时,需要将其改写为C/C++或Java。所以Perl脚本最好用实现支持少量用户数的单一性任务。
可以使用SSJS创建小的数据库应用程序,这是创建基于数据库的工作组级应用系统的一个简单方案。Netscape在现在和将来都会全力支持它,其他的Web服务器也正致力于支持SSJS。
用Java创建大型、任务关键性应用程序(使用Java Servlets、Java Beans等),以便在向NAS移植时最大限度地重用代码。
应当记住没有一种方法可以适合所有情况。每一个站点有不同的需求和侧重点。
CGI脚本适用在:你可能需要频繁改变Web服务器,你有经验丰富的Perl或C/C++开发队伍,你不是非常关心站点的可维护性,你只希望提供一个日常的、用于一般目的的解决方案等情况。
SSJS是数据库驱动的工作组级应用系统的理想解决方案。如果你的开发人员对Java语言已经很熟悉,那么使用Java Servlets对于开发有一定规模的Web程序(包括数据库程序)是非常有用的。
NAS则是满足高流量站点(可能需要扩展至支持成百上千甚至上百万用户)和大型、任务关键性应用的完美解决方案。
方案可以不同,但是我们的最终目的是相同的,那就是使用最低的成本(包括初期成本、开发成本和长期维护成本),为客户提供最好的服务。基于Web服务器的方案目前还有大量应用,但当我们放眼未来,随着应用系统的日益复杂和用户群的日益增长,基于应用程序服务器的解决方案(如NAS)无疑能更好地满足用户的进一步需求。
第三章 JSP (Java Server Pages)
JSP技术是J2EE体系结构中的一个重要组成技术,它为开发人员提供了一个Server端框架,基于这个框架,开发人员可以综合使用HTML、XML、JAVA语言以及其他脚本语言,灵活、快速地创建动态网页内容。
JSP1.1规范扩展了Java Servlet API,目前绝大部分开发商都在其Web服务器和Servlet引擎产品中实现了对JSP的支持。
首先,用户在客户端(浏览器)发出的请求信息被存储在Request对象中并发送给Web服务器,JSP引擎(通常捆绑在Web服务器上)根据JSP文件的指示处理Request对象,或者根据实际需要将Request对象转发给由JSP文件所指定的其他的服务器端组件(如Servlet组件、JavaBean组件或EJB组件等)处理。处理结果则被以Response对象的方式返回给JSP引擎,JSP引擎和Web服务器根据Response对象最终生成JSP页面(JSP Pages),返回给客户端浏览器,这也是用户最终看到的内容。用于客户和服务器之间的通信协议最常用的是HTTP,此外也可以使用特定的私有协议。
在技术实现细节上,JSP的实现实际上借助了Servlet技术,系统在首次载入JSP时自动将其编译成内部的Servlet,JSP对Request对象和Response对象(以及其他隐含对象)的处理最终都是由其对应的Servlet来完成的。对于JSP和Servlet这两种相辅相成的技术,目前比较通用的运用手段是:决定显示页面内容的HTML置于JSP中;而决定显示逻辑和控制的Java代码则置于Servlet中,这种划分可以比较清晰地界定网页开发人员和应用程序开发人员的工作领域和技能领域。
相比较于传统的用于产生动态页面的技术,JSP技术具有很多先天的优势,以下分别予以简述:
与CGI的比较:
JSP能够在多次用户请求期间保持服务对象的状态(因为它能使用Servlet所具有的会话功能),而CGI难以用便捷高效的方法实现这一要求。
JSP通过产生出一个线程来处理用户的一个新的请求,响应时间快,效率高;而CGI则通常是依靠产生一个进程来处理用户的新请求,有时甚至还要启动其他的支持进程(如Perl解释器等),系统开销大,效率低。
JSP通常只需要完成一次系统载入和初始化过程,此后可以常驻内存,直至用户的应用结束。JSP可以运行在预先载入的Java虚拟机中,作为Web服务器的扩展。
与ASP的比较
JSP在技术上的主要竞争对手是Microsoft的ASP,两者在技术上很相似,都支持动态网页的创建、脚本代码和用于实现商业逻辑的组件等,也都提供和企业级应用程序框架的接口(分别是J2EE和Microsoft DNA),但总的来说,JSP在平台通用性、实现机制灵活性等方面具有一定优势。
JSP ASP
运行平台 所有主要的Web服务器平台 主要局限于Microsoft的Web平台
基础开发语言 Java JavaScript或者VBScript
使用组件 JSP Tags、JavaBeans以及Enterprise JavaBeans COM/DCOM
代码翻译 一次 每个事例(instance)一次
与其他Web服务器内置API的比较
许多Web服务器自身提供内置API来实现动态内容创建,如Microsoft IIS的ISAPI、Netscape web server 的NSAPI等,在实际中也有一定应用,但以上技术的一个主要缺点就是平台依赖性强,只能适用于特定平台和Web服务器,不具有可移植性。上述缺陷决定了它无法与JSP竞争。
第四章 Servlets
工作原理及概述
Servlets是用Java语言实现的独立于协议和平台的服务器端组件,它动态扩展了支持Java的服务器,它可以被插入到支持Java的Web服务器中以提供定制服务,包括:
· 增加新的特性服务
· 页面内容的动态改变(Runtime changes)
· 页面显示的动态改变(Runtime changes)
· 对新的标准协议的支持(例如FTP)
· 对用户定制协议的支持
如图所示,Servlets在服务器内部工作,它们不需要图形用户接口,作为Java程序组件,它们根据需要在服务器内部被部署。而使用Servlets的客户多种多样,既有简单的HTML表单,也有复杂的Java Applets。
Servlets 被设计在请求/应答(Request/Response)处理模式下工作,在该模式下,客户向服务器发送请求消息,服务器则通过发送应答消息予以回复。请求消息可以采用如下格式:
· HTTP
· URL
· FTP
· 用户定制协议
在通常情况下,请求和其相关应答可以反映请求时刻客户和服务器的状态,而客户和服务器之间连接的状态无法在多个请求/应答之间保存,而Servlet所提供的会话(Session)机制则可以在多次请求/应答之间保存会话信息。
Servlets有效地扩展了基于请求/应答的服务器(例如Web服务器)的功能,下图显示了一个最简单的应用实例,一个Servlet负责获取来自客户的HTML格式的定单项(order-entity)数据,然后实施商业逻辑(business logic)处理,以便最终更新用户的定单数据库。
Java Servlet API 包括若干Java接口(Java interfaces),全面定义了主机服务器与Servlets之间的连接。Servlet API属于标准Java开发包(JDK)扩展,被包含在如下Java包中:
· javax.servlet
· javax.servlet.http
Servlets API包括了很多有用的特性,如会话跟踪(Session tracking)、表单数据采集(Form data parsing)、共享数据(Shared data)、国际化字符I/O,初始化参数、请求代理(Request delegation)等。
特点及应用
Servlets 是对Java环境的一个功能强大的补充,具有快速、安全、可靠和100%纯Java的优点。因为Servlets被插入到已经存在的服务器中运行,可以有效利用大量现成代码和技术,所有有关网络连接、协议协商、类装载等等工作都可以由服务器代劳,极大地减少了重复工作。
Servlets具有灵活多样的应用:
· Servlets可以并发处理多个请求,相互的请求之间能够被同步,支持应用程序间的协作,应用实例之一是在线会议。
· 复杂的工作可以被设计由多个活动代理(active agents)共同承担,每个代理作为Servlet被实现和载入,各个代理之间可以相互传递数据。
· Servlet可以把请求转发给其他服务器或者其他Servlet,这一技术可以有效地在提供同一服务内容的多个服务器间实现负载平衡。
由于其强大功能和灵活性,Servlets对于系统体系结构规划具有重要意义,它们可以实施基于中间层(middle-tier)的应用处理,可以作为客户的Proxy代理,甚至可以通过支持新的协议或特定服务来充实或更新中间层的服务内容。
中间层处理
在通常所说的三层客户/服务器系统(three-tier client/server systems)中,中间层作为应用程序服务器(Application Server),连接了前端客户(如Web浏览器)和后端服务及数据。通过中间层的使用,大量处理工作得以从前、后端分流,使前端客户更轻、更快,使后端服务更加专注其任务。
Servlets非常适合用于中间层处理,一个明显的好处是可以简化连接管理,数据库连接需要较大的系统开销,通过建立和有效管理数据库连接池(pool),一组Servlets可以容易地处理成百上千个客户连接。
Servlets在中间层的作用还包括:
· 商业规则强化(Business rule enforcement)
· 事务管理(Transaction management )
· 建立客户与冗余服务器组的映射
· 支持不同类型客户(例如纯HTML客户和Java兼容客户)
代理服务器
当被用于支持Applets时,Servlets可以作为Applets的代理。这一作用非常重要,因为Java的安全机制只允许Applets建立当地到它们的下载服务器的连接。
如果一个Applet企图建立到位于其他主机的数据库服务的连接,一个Servlet可以代表它完成上述工作。
协议支持
Servlet API提供了服务器和Servlets之间的紧密连接,它们允许为服务器增加新的协议支持。Servlet API包中已经实现了对HTTP的很好支持。从本质上说,任何遵循请求/应答工作模式的协议都可以通过一个Servlet来实现,包括:
· SMTP
· POP
· FTP
目前主要的Web服务器都实现了对Servlets的支持,而越来越多的其他类型的应用程序服务器也开始实现对Servlets的支持。由于HTTP是最为常用的协议之一,Servlets在基于HTTP的系统中得到了最为广泛的应用。相对于其他服务器端技术如CGI、Web服务器API扩展(NSAPI、ISAPI、Apache Modules)等,Servlets有如下优势:
· 由于使用了不同的处理模型和处理机制,Servlets在速度和效率上高于CGI,在功能和实现灵活性上也要强于CGI,有取代CGI的趋势。
· Servlets使用了被许多Web服务器产品支持的标准API,具有较强通用性。
· Servlets具有Java编程语言的所有优点,包括易于开发、平台独立性等。
· Servlets可以访问基于Java平台和Java技术的大量API,能很好地和目前主流体系结构(如J2EE)融合,具有高灵活性和高扩展性,适用于构造大型复杂的应用系统。
第五章 iPlanet的应用程序服务器
领先的iPlanet E-Commerce方案
作为SUN Microsystem与Netscape战略联盟的产物,iPlanet E-Commerce解决方案旨在帮助企业借助Internet强大功能,实现"网络经济"。凭借其出色的技术,iPlanet已经成为该领域无可争议的行业领导者。 Iplanet E-Commerce解决方案基本构架如图:
在层次体系结构上,iPlanet E-Commerce遵循多层客户/服务器模型,在多层模型中,中间层通常要处理来自客户的请求,执行复杂的商业逻辑,同时要处理来自后端系统和数据库的相关企业数据,并且替客户屏蔽数据复杂性。Application Server属于中间层服务器,目前比较成熟的产包括:iPlanet的iAS6.0/NAS4.0、IBM的WebSphere3.0和BEA的WebLogic5.1等。
以iPlanet的NAS(Netscape Application Server)为例,Application Server通常实现如下功能:
· 接受来自客户的请求
· 在内部运行相应的Java或C++例程
· 与数据库交互,获得结果集
· 按一定模板整理结果集并输出给客户
· 服务失败时可以自动恢复 等
iPlanet的应用程序服务器(iAS/NAS)
基本服务和扩展
iAS/NAS为用户应用程序提供了一个功能强大的运行环境,如下图:
除了由开发人员编写的核心应用程序逻辑之外,iAS/NAS为核心程序的开发提供了很多基本服务和预先内置的扩展,包括:
会话管理
结果集缓存
连接池管理
负载平衡
数据访问引擎
模板引擎
线程管理
HTTP流等
应用程序开发模型
基于iAS/NAS的应用程序的开发模型分为以下四层:
· 显示页面布局层(Presentation page layout)
· 显示逻辑层(Presentation logic)
· 商业逻辑层(Business logic)
· 数据访问层(Data access)
显示页面布局层
主要由JSP(Java Server Page)构成,用于生成动态页面内容。JSP由HTML、JSP标签和Java语言混合编写。
显示逻辑层
主要由Servlets构成,每个Servlet实际上是小的Java类或组件,在该层用于实现显示页面逻辑关系和页面导航,同时也负责创建和激活商业组件(如EJB)
商业逻辑层
主要由EJB(Enterprise Java Bean)构成,每个EJB组件负责封装应用程序的商业逻辑、商业规则和商业对象
数据访问层
主要由EJB构成,EJB组件使用JDBC和查询文件(query files)对后端数据库操作,访问企业数据。
应用程序模型中包括的开发组件还有AppLogic、HTML模板、查询文件、扩展等。
应用程序模型示意图如下:(图中显示页面布局层和显示逻辑层被合并为显示层)
最优秀的企业级应用程序服务器
我们有理由认为iAS/NAS是同类产品中最优秀的,下面是我们将iAS/NAS与其他两个主要竞争对手(IBM WebSphere及BEA WebLogic)相比较得到的结果。
iAS/NAS与IBM WebSphere的比较
IPlanet Application Server6.0/Netscape Application Server4.0 IBM WebSphereAdvanced Edition 3.0
平台支持 操作系统 NT4.0 SP3 Solaris 2.6, 7 HP-UX DEC Unix (Compaq Tru64) AIX Java JDK 1.1.7 JDK 1.2 Web Server NES 3.6 NES 4.0 Apache IIS 通过本地API与Web Server连接,性能高 操作系统: NT AIX Solaris Java JDK 1.1.7(w/limitations) Web Server NES IIS Apache IBM WebServer 仅通过CGI与Web Server连接,性能低
应用程序模型 完全的J2EE兼容 被评价为最快、最可靠的Java应用程序服务 器(GIGA, 8/27/99) 面向J2EE 虽然IBM在市场上也宣称它是最完善、 最健壮的产品,但至少目前还不是。
开发工具 具有广泛的开发工具支持: 1. NAB/iAB (Netscape/iPlanet Application Builder) 2. Basic VisualCafe integration.3. NEB/iEB (Netscape/iPlanet Extension Builder) ,用于建立定制集成NAS/iAB扩展. 只支持IBM的开发工具 1. Websphere Studio 2. 支持VisualAge for Java Enterprise 3 3. 通过Websphere Admin. Console 部署EJB
扩展性 水平扩展性: 跨服务器间的负载平衡 复杂的程序分组(Application partitioning) 动态的负载平衡 动态的组件共享 Entities Beans可以在Java引擎间复制垂直扩展性: 一个App Server上可以容易增加Java引擎, 以充分利用系统资源。 水平扩展性: 跨应用程序服务器间的负载平衡 无程序分组(Application partitioning) 无动态的负载平衡垂直扩展性: 不详
性能 很高的性能,建立在以下技术基础上:1. 驱动器级的数据库连接池2. 数据库row pre-fetching3. data streaming 4. 多进程,多线程,完全可配置的app. Server5. 优化的与web servers 间通信 6. JSP load balancing , JSP result caching7. RMI/IIOP access to EJBs includes server side load balancing.8. Performance optimization for distributed clustering 9. 在吞吐量/响应时间方面性能优秀10. 新的服务器内部负载平衡计划,可提高处理分布式负载的性能11. 具有主机内/主机间的高扩充性 负载平衡方案不能由用户配置,只能在三种预配置方案中选择。
可用性 1. 可保存和复制分布式用户会话信息及分布式应用程序状态信息2. 提供高效、易扩展的方式保存持久状态和会话信息3. 为以下组件提供分布、负载平衡和复制服务:EJBs,JSPs/ServletsJDBC-based data sourcesBackend integration access4. 动态部署和扩展应用程序(不需停止服务器)5. 动态配置进程和服务器(不需停止服务器) IBM Websphere Advanced Edition 不成熟,它依靠数据库来共享/复制会话状态。IBM为3.0版本重新设计了会话保存方法,但效率和扩展性并不好,需要重起服务器。
安全性 支持: X.509 (通过目录服务器) RSA 加密, SSL, SHTTP 完全实现EJB安全性; ACLs 基于LDAP的用户认证 支持: X.509 SSL
集成性 支持实时、同步连接通过应用程序(EcXpert),支持异步、松耦合连接Legacy Applications (实时连接): MQ Series CICS Tuxedo Peoplesoft SAP/R3 Custom Apps数据库:Oracle / Informix / Sybase DB2 / SQL Server / ODBC 客户:Web (HTTP) 通过NCF支持基于Corba的客户( C++) 通过NCOM支持基于COM的客户 ( ActiveX) 通过RMI/IIOP支持Java客户 Websphere似乎不支持实时-同步连接 Legacy Applications: CICS MQSeries IMS 不支持Tuxedo 和Peoplesoft 数据库:Oracle / Informix Sybase / DB2 客户: Web / Corba / COM
iAS/NAS与BEA WebLogic的比较
iAS6.0 BEA WebLogic Server5.1 + Enterprise 5.1
产品细节 JDK 1.2 / EJB 1.1 Servlets 2.2 / JSP 1.1 JDBC 2.0 / RMI/IIOP 1.0 JMS 1.0 / JNDI 1.2 JTA 1.0 / JavaMail 1.1 JAF 1.0 / Security 利用XML实现应用程序组装和部署 JDK 1.2 / EJB 1.1 Servlets 2.2 / JSP 1.1 JDBC 2.2 / RMI/IIOP 1.0 JMS 1.0 / JNDI 1.2 JTA 1.0 / JavaMail 1.1 JAF 1.0 / Security 手工实现应用程序组装和部署 对象引用和映射功能需要第三方支持(TOPLink) 新近注册J2EE许可 (4/00)
性能和扩展性 支持跨应用程序服务器的负载平衡(每app,每JSP /servlet / EJB)复杂的程序分组(Application partitioning)动态的负载平衡动态的组件共享健壮的设计一个App Server上可以容易增加Java引擎,以充分利用系统资源。Entities Beans可以在Java引擎间复制iAS的高性能建立在以下技术基础上:1. 驱动器级的数据库连接池2. 数据库row pre-fetching3. data streaming 4. 多进程,多线程,完全可配置的app. Server5. 优化的与web servers 间通信iAS6.0还包括以下增强功能:1. JSP load balancing2. JSP result caching3. RMI/IIOP access to EJBs includes server side load balancing.4. Performance optimization for distributed clustering 5. 在吞吐量/响应时间方面性能优秀6. 新的服务器内部负载平衡计划,可提高处理分布式负载的性能7. 具有主机内/主机间的高扩充性 支持跨应用程序服务器的负载平衡,但无法作到完全透明、无程序分组、无动态的负载平衡不好的设计需要在每CPU上运行单独的app server才能最大利用主机资源BEA的负载平衡计划不能被管理员配置,只提供三种预配置方案: round robin, weighted round robin 和random. 从内部看,iAS显示出具有比WebLogic Server.当前版本更快的速度,尤其是在拥挤的情况下WebLogic具有下列功能:数据库连接池数据库row pre-fetching
可用性 1.可保存和复制分布式用户会话信息及分布式应用程序状态信息2.提供高效、易扩展的方式保存持久状态和会话信息3.为以下组件提供分布、负载平衡和复制服务: EJBs,JSPs/ServletsJDBC-based data sourcesBackend integration access4.动态部署和扩展应用程序(不需停止服务器)5.动态配置进程和服务器(不需停止服务器) 通常被认为不是一个高可用性的解决方案WebLogic有比较好的服务分簇技术,但该技术相对较新,尚不成熟 WebLogic Enterprise 是: 建立在BEA M3产品基础之上 与WebLogic产品线上其他app servers使用不同的代码基
管理 iPlanet Deployment Tool:1. 应用程序集中式组装,分组和服务器簇范围的动态部署2. 能够进行分组的应用程序负载平衡3. 支持同一簇上跨app server间的J2EE 应用程序打包和分组 iPlanet Application Server Administrator (iASA) 1.远程管理服务器和分布式应用程序 2.动态配置进程和服务器3.完善的日志功能4.事件日志和错误分析 5.领先的管理功能 6.启动和运行时的监视可配置iPlanet Directory Server 提供集中式簇管理,易于管理企业管理:提供SNMP代理,可与流行的企业管理主控制台集成(如OpenView, UniCenter和Tivoli) EJB Deployment Tool:1. 仅仅是个EJB编译器和部署描述向导,而不是一个部署工具,管理员还是需要手工将EJB部署到运行环境中去WebLogic Console:1. BEA 仅仅提供粗略的性能调优和操作监视功能2. BEA的Weblogic Server application deployment & server administration是基于对每个server属性文件的手工修改实现3. 日志功能有限,仅支持记录到文件,日志分级仅能在启动时配置4. 仅在启动时监视可配置企业管理:SNMP模块被单独出售。