引言 J2EE 规范 对将 J2EE 应用程序打包成一个文件扩展名为 EAR(EntERPrise Archive(企业压缩文档))的文件进行了定义,并且规定这些应用程序彼此独立。然而,该规范对于如何最佳部署应用程序却只字未提。您是应该选择在每台应用程序服务器上只部署一个 J2EE 应用程序(EAR 文件)?还是应该在单独一台应用程序服务器上部署多个 J2EE 应用程序(EAR 文件)? IBM® WebSphere® Application Server支持这两种选择。您应该选择哪种方式?本文探讨了针对这两种选择您需要考虑的许多问题。当您阅读本文时,请记住:一个 EAR 文件可以包括一个或多个 WAR(Web 应用程序压缩文档(Web Application Archive))文件(我们将单独讨论将若干个 WAR 文件打包成一个 EAR 文件的打包准则,本文不涵盖这方面的内容)。 性能 一般来说,一台机器上的进程(应用程序服务器、HTTP 服务器进程等)数越少,在这台机器上发生内存交换、页面调度或上下文切换的可能性就越小。我们期望的结果是操作系统将投入较少的资源用于进程管理,从而使更多的系统资源能够被用于处理应用程序工作负载。这样会改善应用程序性能。 请考虑有 20 个应用程序的情况;在这种情况下,您将创建 20 台应用程序服务器,每个应用程序一台。如果每台服务器都有一个 256 MB 的 Java 堆,那么这些应用程序服务器所要求的内存将至少为 5 GB。在极端情况下,如果大量应用程序被部署到一个节点,这些应用程序服务器将不得不被共享;否则,物理内存将被用光。对于这种情况,CPU 资源也是一个限制因素,尽管通常只有在机器满负载(被定义为 85% 的 CPU 正在使用中)时(因为进程级的内务处理(housekeeping)任务会消耗大量的 CPU 周期),人们才会关注 CPU 资源。当然,通常只有当运行接近一台给定机器的内存极限或 CPU 极限时,进程管理的开销才会成为一个问题。幸运的是,为了顾及工作负载峰值(spike)或停机(outage),大多数组织采用的标准做法是以 50% 的 CPU 利用率运行生产服务器,所以这种极端情况很少发生。 作为一个示例,请考虑一下这个简单的测试案例:两个应用程序在各种不同负载下运行,它们先是各自被部署在一台应用程序服务器上,然后被部署在单独一台应用程序服务器上。所有的测试都在具有 2 GB RAM、运行 iPlanet 6.01 和 WebSphere Application Server 4.03 高级版的 2 CPU HP-UX 服务器上运行。Oracle 8.1.7 数据库单独使用一台服务器。
从上面的测试案例中可以看到,只用一台应用程序服务器运行两个应用程序会使性能得到显著改善,改善程度从 9.6% 到 18.7% 不等。尽管每个应用程序都呈现对性能有正面影响,但因每个应用程序施加的工作负载不同,所以改善程度也有所不同。应用程序 A 针对每个请求执行几次数据库选择以及一次更新,而应用程序 B 针对每个请求则只执行一次或两次数据库选择,且每隔 8 到 10 个请求进行一次更新。在任何情况下,对于那些性能很重要并且带有大量应用程序的环境来说,减少应用程序服务器数量可以显著地改善性能。在操作系统资源相同的条件下,将应用程序结合到共享的应用程序服务器中可以得到更好的应用程序性能。不过,每次都要进行测试以确保对于您的环境而言确实能够提高性能,这是很重要的。 性能测试和问题确定 要确实获得单独一台应用程序服务器所能提供的可能的性能优势,您应该用两种方式测试性能和可伸缩性。第一种方式,测试每台应用程序服务器只有一个应用程序的情况,以验证一个给定的应用程序的性能和可伸缩性,从而消除特定于该应用程序的任何应用程序瓶颈。第二种方式,同将被部署到同一台应用程序服务器上的所有其他应用程序一起进行测试。另外,请记住:一次测试多个应用程序代表的是一种比分别测试各个应用程序更复杂的情况。负载测试需要多个脚本,每个要同时运行的应用程序一个脚本。要彻底解决共享应用程序服务器的应用程序可能引发的问题,系统地测试产品化之前的多个系统是至关重要的。如果您选择在单独一台应用程序服务器上部署多个应用程序并且出现了性能问题,那么确定哪个应用程序出了问题就更加困难。幸运的是,您可以使用 WebSphere Application Server 提供的许多性能监视工具,还可以使用第三方提供的用于这一目的的工具。 应用程序可伸缩性 在某些情况下,应用程序开发者可能会选择不按照 Harvey Guther 在 WebSphere Application Server Development Best Practices for Performance and Scalability 中概述的应用程序开发最佳实践去做。由于 HTTP 会话对象的大小,您在选择如何部署时可能会受到限制。有些读者可能碰到过这样的应用程序,这些应用程序中的 HTTP 会话对象的大小不仅要求在每台应用程序服务器上只部署一个应用程序,还要求创建多个克隆。在极端情况下,当会话对象的内存要求用光甚至超过了可用的 JVM 堆的时候,这样做是有必要的。例如,对于一个 1.0 MB HTTP 的会话对象和 1,000 个连接的用户,仅会话对象的内存要求就是 1.0 GB(1000 x 1.0 MB)。当然,您可以更改内存中存储的会话数量,但会话对象将溢出内存或者被写入数据库,这取决于配置。这两种选择都会影响性能,尤其是在会话对象很大的情况下。其他的应用程序瓶颈可能还要求将多台应用程序服务器(克隆)用于单个应用程序,这仅仅是为了满足可伸缩性和性能方面的要求。操作控制权和维护 当您选择在单独一台应用程序服务器上运行两个 J2EE 应用程序(例如应用程序 A 和应用程序 B)时,您应该考虑下列问题。同一个人有停止在应用程序服务器上运行的所有应用程序的权限吗?尽管 WebSphere Application Server 使您能够从管理控制台和 wscp 启动和停止一台应用程序服务器内部的各个应用程序,但是,一个组织仍然需要考虑如何分配操作控制权。 有些改动(例如安全性改动)需要重新启动应用程序服务器才会生效。如果两个或更多个应用程序共享一台应用程序服务器,这会引起相互冲突的需要。此外,同一台应用程序服务器上的所有应用程序都以相同的操作系统身份运行。这样就存在安全性隐患,因为与一台应用程序服务器上的应用程序相关联的文件许可权是归这个操作系统身份所有的。在这种情况下,您无法保护与一个应用程序相关联的文件,使这些文件不被这台应用程序服务器上的其他应用程序访问,因为这些应用程序共享相同的操作系统特权。如果您不能接受这种情况,那么您将需要为每个应用程序建立一台应用程序服务器以提供安全性保护。 一个组织打算怎样处理应用程序升级?要注意的事项包括对应用程序构建的控制以及对应用程序服务器过程的控制。因为 EAR 不仅是一个部署时(deploy-time)组件,而且还是一个构建时(build-time)组件,所以情况还可能取决于谁可以触发构建行为。虽然通常都建议 EAR 应是完全独立的,但是事实上并不是必须如此,而且有许多 EAR 并非完全独立的情况。一个 EAR 中的 EJB 或 Servlet 依赖于另一个 EAR 中的 EJB 并可以通过全局 JNDI 名称空间进行访问,这并不罕见。如同前面所提到的,WebSphere Application Server 使您能够停止和启动各个应用程序,但是在某些情况下,一个应用程序升级可能要求您启动和停止整台应用程序服务器。一个组织是愿意停止或启动整台运行着多个应用程序的应用程序服务器来执行更新呢?还是希望能一个应用程序一个应用程序地执行更新呢?如果每个应用程序有一台应用程序服务器,这样做就会更容易,不过,对于一台应用程序服务器上有多个应用程序的情况,也可以做到这一点。 应用程序如果要求用户在 JVM 类路径中添入某些项或者要求用户设置全局 JVM 系统属性,那么应用程序本身就有可能引入相互冲突的需要。选择类装入器可见性也会导致部署不兼容性问题,例如在应用程序采用单一的 singleton 时使用服务器可见性。在单个 JVM 中按这样的体系结构部署两个或更多个应用程序不可能有服务器可见性。Keys Botzum 在 J2EE Packaging and Common Code中更详细地讨论了如何部署和打包应用程序,Rick Robinson 在 Developing and Deploying Modular J2EE Applications with WebSphere Studio Application Developer and WebSphere Application Server中更详细地讨论了如何选择类装入器。 在极端情况下,编写得很糟糕的应用程序会导致 JVM 挂起或发生故障,并因而影响其他表面上不相关的应用程序。考虑一下这种情况:一个编写得很糟糕的应用程序启动了许多线程,或者消耗了许多内存或其他共享资源(如数据库连接)。在这个示例中,有几种可能的情况,一个应用程序可以接管一台应用程序服务器而让其他的应用程序处于饥饿状态。同样,性能特征需要兼容。事实上,调优本文的性能测试部分所使用的两个应用程序花了本文作者相当多的时间和精力。经过系统的测试和细心的规划,您仅可以识别和修复应用程序或资源冲突。 故障转移和工作负载管理 应用程序部署还取决于故障转移要求。WebSphere Application Server 4.x 通过服务器组提供故障转移和工作负载管理定义。服务器组支持将多个应用程序服务器组成群集。结果,您将只想把应用程序分组到同一个应用程序服务器中,或分组到有类似的可伸缩性和/或故障转移需要的服务器组中。请考虑下面的图 2 中描述的部署备选方案。哪一个方案是供故障转移使用的? 图 2. 在这种方案中,每台应用程序服务器上只有一个应用程序,一台应用程序服务器发生故障将导致与该应用程序服务器相关联的应用程序的服务丢失。请记住:大多数环境都意识到上面描述的两种部署选择都不是真正容错的,因为单独一台物理服务器的丢失会造成停机。下面的图 3 中描述了一种更典型的方案。这种部署方案将物理服务器作为单个故障点除去。如需更多关于如何使用 WebSphere Application Server 规划和实现高度可用的环境的信息,请参阅 Modjeski 等人著的白皮书 Failover and Recovery in WebSphere Application Server Advanced Edition 4.0。 图 3.结束语 虽然本文作者支持在多个 J2EE 应用程序之间只共享一台 JVM/应用程序服务器,但是在许多情况下,这样可能并不切合实际。对于许多组织来说,在每台应用程序服务器上部署一个应用程序是一种更高效的方式,把时间集中花在对各个应用程序性能进行最优化上。另外,在某些情况下,或者出于操作需要,或者由于应用程序设计,应用程序会要求具有它自己的 JVM。一般来说,任务关键的应用程序或大型应用程序可能出于以上原因会想要在它们自己的 JVM 中部署,而较小的或不那么重要的应用程序或相互联系的应用程序(人力资源应用程序,尤其是那些共享相同类型的后端的应用程序)可能想要共享 JVM。例如,所有的 Siebel 应用程序可能想要共享一个 JVM,所以如果 Siebel 出了故障,则只有这些应用程序受到影响。 多个 J2EE 应用程序共享一些应用程序服务器通常能改善性能,尤其是对于有许多应用程序的大型环境来说。然而,与每台应用程序服务器运行一个 J2EE 应用程序相比,这是以操作灵活性为代价的。情况经常如此,要涉及到许多折衷,作出什么选择将取决于组织打算怎样管理它们的应用程序、它们的安全性要求、它们的职员在应用程序管理和应用程序设计方面的技能、应用程序可用性要求以及它们的过程成熟度。 (责任编辑:admin) |