很多成功的企业应用程序都是使用 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 原理和设想
Java EE 平台的创建目的就是为企业到客户(B2C)和企业到企业(B2B)应用程序提供支持。企业发现了 Internet 的价值之后就开始使用它增强与合作伙伴和客户之间的现有业务流程。这些应用程序通常要与一个现有企业集成系统(EIS)进行交互。大多数常见基准测试(测试 Java EE 服务器的性能和可伸缩性)— ECperf 1.1、SPECjbb2005 和 SPECjAppServer2004— 的用例都将这一点反映到了 B2C、B2B 和 EIS 中。类似地,标准的 Java PetStore 演示也是一个典型的电子商务应用程序。
很多有关 Java EE 架构可伸缩性的明显和暗含的设想都反映在基准测试中:
从客户机角度来看,请求吞吐量是影响性能的最重要特性。
事务持续时间是最重要的性能因素,并且,缩减所有个体事务的持续时间将改善应用程序的总体性能。
事务之间通常都是彼此独立的。
除长期执行的事务以外,只有少数业务对象会受事务影响。
应用服务器的性能和部署在同一管理域的 EIS 会限制事务的持续时间。
通过使用连接池可以抵消一定的网络通信成本(在处理本地资源时产生)
通过对网络配置、硬件和软件进行优化,可以缩短事务持续时间。
应用程序所有者可以控制内容和数据。在不依赖外部服务的前提下,向用户提供内容的最重要限制因素是带宽。
性能和可伸缩性问题
Java EE 平台最初的设计目的是使用部署在单个管理域中的资源操作服务。其设想的前提是 EIS 事务生存期较短并且请求处理较快,从而使平台能够支持较高的事务负载。
很多新兴架构方法和模式 — 例如对等(P2P)、面向服务架构和统称(非正式地)为 Web 2.0 的新型 Web 应用程序 — 不满足这些假设。在这些应用程序的使用场景中,请求处理将占用更长的时间。因此,当使用 Java EE 方法开发 Web 2.0 应用程序时,将出现严重的性能和可伸缩性问题。
这些设想产生了以下 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。