如果 Web 2.0 应用程序使用的是基于标准的 Java Platform, Enterprise Edition 5 (Java EE) 开发方法,那么将会面临着严重的性能和可伸缩性问题。这是因为,大量支持 Java EE 平台的底层设计原理(尤其是使用同步 API 的应用)并不适合 Web 2.0 解决方案的需求。本文将解释 Java EE 和 Web 2.0 方法之间的不一致性,并对一些使用 Java 平台开发异步 Web 应用程序的解决方案进行评估。
很多成功的企业应用程序都是使用 Java EE 平台构建的。但是,Java EE 的设计原理并不能够有效地支持 Web 2.0 应用程序。深入了解 Java EE 和 Web 2.0 原理之间的脱节可帮助您制定明智的决策,从而使用各种方法和工具在一定程度上解决这种脱节。本文将解答 Web 2.0 和标准 Java EE 平台缘何成为失败的组合,并演示为何由事件驱动的异步架构更适合 Web 2.0 应用程序。本文还介绍了一些框架和 API,它们通过支持异步设计使得 Java 平台更加适合 Web 2.0。
Java EE 平台的创建目的就是为企业到客户(B2C)和企业到企业(B2B)应用程序提供支持。企业发现了 Internet 的价值之后就开始使用它增强与合作伙伴和客户之间的现有业务流程。这些应用程序通常要与一个现有企业集成系统(EIS)进行交互。大多数常见基准测试(测试 Java EE 服务器的性能和可伸缩性)— ECperf 1.1、SPECjbb2005 和 SPECjAppServer2004的用例都将这一点反映到了 B2C、B2B 和 EIS 中。类似地,标准的 Java PetStore 演示也是一个典型的电子商务应用程序。
很多有关 Java EE 架构可伸缩性的明显和暗含的设想都反映在基准测试中:
- 从客户机角度来看,请求吞吐量是影响性能的最重要特性。
- 事务持续时间是最重要的性能因素,并且,缩减所有个体事务的持续时间将改善应用程序的总体性能。
- 事务之间通常都是彼此独立的。
- 除长期执行的事务以外,只有少数业务对象会受事务影响。
- 应用服务器的性能和部署在同一管理域的 EIS 会限制事务的持续时间。
- 通过使用连接池可以抵消一定的网络通信成本(在处理本地资源时产生)
- 通过对网络配置、硬件和软件进行优化,可以缩短事务持续时间。
- 应用程序所有者可以控制内容和数据。在不依赖外部服务的前提下,向用户提供内容的最重要限制因素是带宽。
这些设想产生了以下 Java EE API 构建原理:
- 同步 API。Java EE 在很多应用中都需要使用同步 API(重量级并且繁琐的 Java Message Service (JMS) API 基本上是惟一的例外)。这种需求更多地源于可用性的需要,而非性能需求。同步 API 易于使用并且开销较低。但需要处理大型多线程时,则会出现严重问题,因此 Java EE 严格限制未受控制的多线程处理。
- 有限的线程池。人们很快发现线程是种重要的资源,并且当线程数量超过某一界限后,应用服务器的性能将显著下降。然而,根据每个操作都很短暂的设想,这些操作可以分配到一组有限的线程中,从而维持较高的请求吞吐量。
- 有限的连接池。如果只使用一个数据库连接,则很难获得最优的数据库性能。虽然一些数据库操作可以并行执行,但是增加额外的数据库连接只能将应用程序提速到某一点。当连接数达到某一值后,数据库性能将开始下滑。通常,数据库连接的数量要小于 servlet 线程池中可用线程的数量。因此,连接池在创建时允许向服务器组件 — 例如 servlet 和 Enterprise JavaBeans (EJB) — 分配一个连接并在以后返回给连接池。如果连接不可用,组件将等待阻塞当前线程的连接。因为其他组件只对连接占用很短的时间,因此这种延迟通常较短。
- 固定的资源连接。应用程序被假设只使用很少一些外部资源。与各个资源的连接工厂通过 Java Naming and Directory Interface (JNDI)(或 EJB 3.0 的依赖性注入)获得。实际上,支持与不同 EIS 资源进行连接的主要 Java EE API 只有企业 Web 服务 API。其他 API 多数都假设资源是固定的并且只有诸如用户凭证这样的额外数据应该提供给开放连接操作。
在 Web 1.0 中,这些原理玩转得非常好。可以将一些独特的应用程序设计为遵守这些规则。但是,这些原理不能有效支持 Web 2.0。
Web 2.0 应用程序具有很多独特需求,因此,不适合将 Java EE 用于 Web 2.0 实现。其中一个需求就是,Web 2.0 应用程序更多地通过服务 API 使用另一个 Web 2.0 应用程序,而不是使用 Web 1.0 应用程序。Web 2.0 应用程序的一个更为重要的因素是,极度倾向于用户到用户(C2C)交互:应用程序所有者只生成一小部分内容;用户负责生成大部分内容。
在 Web 2.0 环境中,聚合应用程序经常使用通过 SOA 服务 API 公开的服务和提要。这些应用程序需要在 B2C 环境中使用服务。例如,一个聚合应用程序可能从三个不同的数据源提取数据,如天气信息、交通信息和地图。检索这三种独特数据所需的时间延长了总的请求处理时间。不管数据源和服务 API 的数量是否增加,用户仍然期望得到具有高反应度的应用程序。
诸如缓存这类技术可以缓解延迟问题,但是不适用于所有场景。比如,可以缓存地图数据来减少响应时间,但通常并不适合将搜索查询结果或者实时交通信息进行缓存。
服务调用本来就是一种高延迟过程,在客户机和服务器上通常只分配很小一部分 CPU 资源。Web 服务调用的持续时间很大一部分用于建立连接和传输数据。因此,通常来讲,提升客户端或服务器端的性能对于减少调用持续时间效果甚微。
Web 2.0 对用户参与的支持引发了另外一大挑战,因为应用程序要处理来自每个活动用户的更多数量的请求。下面这些理由证明了这一点:
- 因为大多数事件是由其他用户的操作引起的,因此会引发更多相关事件,并且用户具备更强大的能力来生成事件。这些事件通常使用户能够更加积极地使用 Web 应用程序。
- 应用程序为用户提供了更多的用例。Web 1.0 用户仅仅可以浏览类别、购买商品并跟踪他们的订单处理状态。现在,用户可以通过论坛、聊天、聚合等等方法与其他用户进行积极地交流,这将产生更高的通信负载。
- 如今的应用程序越来越多地使用 Ajax 改善用户体验。与普通 Web 应用程序的页面相比,使用 Ajax 的 Web 页面加载要慢一些,因为页面是由一些静态内容、脚本(可能会非常大)和一些发往服务器的请求组成。加载完成后,Ajax 页面通常会向服务器生成一些短小的请求。