技术开发 频道

Java EE 迎合 Web 2.0

  【IT168 技术文章】

        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 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 带来的巨变

  Web 2.0 应用程序具有很多独特需求,因此,不适合将 Java EE 用于 Web 2.0 实现。其中一个需求就是,Web 2.0 应用程序更多地通过服务 API 使用另一个 Web 2.0 应用程序,而不是使用 Web 1.0 应用程序。Web 2.0 应用程序的一个更为重要的因素是,极度倾向于用户到用户(C2C)交互:应用程序所有者只生成一小部分内容;用户负责生成大部分内容。

  SOA + B2C + Web 2.0 = 高延迟

  在 Web 2.0 环境中,聚合应用程序经常使用通过 SOA 服务 API 公开的服务和提要。这些应用程序需要在 B2C 环境中使用服务。例如,一个聚合应用程序可能从三个不同的数据源提取数据,如天气信息、交通信息和地图。检索这三种独特数据所需的时间延长了总的请求处理时间。不管数据源和服务 API 的数量是否增加,用户仍然期望得到具有高反应度的应用程序。

  诸如缓存这类技术可以缓解延迟问题,但是不适用于所有场景。比如,可以缓存地图数据来减少响应时间,但通常并不适合将搜索查询结果或者实时交通信息进行缓存。

  服务调用本来就是一种高延迟过程,在客户机和服务器上通常只分配很小一部分 CPU 资源。Web 服务调用的持续时间很大一部分用于建立连接和传输数据。因此,通常来讲,提升客户端或服务器端的性能对于减少调用持续时间效果甚微。

  更好的交互性

  Web 2.0 对用户参与的支持引发了另外一大挑战,因为应用程序要处理来自每个活动用户的更多数量的请求。下面这些理由证明了这一点:

  因为大多数事件是由其他用户的操作引起的,因此会引发更多相关事件,并且用户具备更强大的能力来生成事件。这些事件通常使用户能够更加积极地使用 Web 应用程序。

  应用程序为用户提供了更多的用例。Web 1.0 用户仅仅可以浏览类别、购买商品并跟踪他们的订单处理状态。现在,用户可以通过论坛、聊天、聚合等等方法与其他用户进行积极地交流,这将产生更高的通信负载。

  如今的应用程序越来越多地使用 Ajax 改善用户体验。与普通 Web 应用程序的页面相比,使用 Ajax 的 Web 页面加载要慢一些,因为页面是由一些静态内容、脚本(可能会非常大)和一些发往服务器的请求组成。加载完成后,Ajax 页面通常会向服务器生成一些短小的请求。

  与典型的 Web 1.0 应用程序相比,这些因素往往会生成更多的服务器通信量和请求数。在高负载期间,这种通信量难于控制(然而,Ajax 也提供了更多的机会对通信量进行优化;与支持相同用例的简单 Web 应用程序相比,Ajax 生成的通信量通常更少)。

  更多内容

  Web 2.0 的特征就是比上一代 Web 应用程序拥有更大量的内容和更大的规模。

  在 Web 1.0 世界中,内容通常只有经过业务实体的明确允许后才被发布到公司网站。企业需要控制所显示的文本的每个字符。因此,如果计划发布的内容超出了框架的大小限制,则要对内容进行优化或将其分成几个较小的部分。

  Web 2.0 站点的一个特性就是不会限制内容的大小或创建。大部分 Web 2.0 内容由用户和社区生成。组织和企业仅仅提供工具实现内容创建和发布。由于使用了大量图像、音频和视频,内容的大小也相应增加。

  持久连接

  建立客户机到服务器的新连接会耗费很多时间。如果某些交互在预期之中,则建立一次客户机/服务器通信,然后重复使用该连接,这样做会获得更高的效率。持久连接对于发送客户机通知也很有用。但是 Web 2.0 应用程序的客户机通常位于防火墙之后,一般很难或不能直接建立服务器到客户机的连接。Ajax 应用程序需要发送请求轮询特定事件。要减少轮询请求的数量,一些 Ajax 应用程序使用 Comet 模式:该服务器被设计为在某个事件发生以前保持等待状态,然后发送应答,同时保持连接打开。

  对等消息传递协议,如 SIP、BEEP 和 XMPP,逐渐使用持久连接。流式直播视频也从持久连接中获益良多。

  更容易发生 Slashdot 效应

  Web 2.0 应用程序拥有大量的访客,这一点使某些站点更容易发生 “Slashdot 效应” — 如果某个流行的 blog、新闻站点或社会型网站提及某个站点时,该站点的通信量负载会猛增。所有 Web 站点都应该准备好处理比普通负载高几个数量级的通信量。这种情况下更重要的一点是,站点在如此高的负载下不会发生崩溃。

  延迟问题

  与操作吞吐量相比,操作延迟对 Java EE 应用程序的影响更大。即使应用程序使用的服务可以处理大量操作,延迟仍然保持不变或者进一步恶化。目前的 Java EE API 还无法很好地处理这一情况,因为这种情况违背了这些 API 设计中暗含的延迟假设。

  在使用同步 API 时,为论坛或 blog 中的大型页面提供服务将开启一个处理线程。如果每个页面需要一秒钟的服务时间(例如 LiveJournal 这类应用程序,包含很多较大的页面),并且线程池包含 100 个线程,那么一秒钟的时间内无法为超过 100 个页面提供服务 — 这种性能无法接受。增加线程池中的线程数量收效甚微,因为当线程池中的线程数量增加时,应用程序-服务器性能将开始降低。

  Java EE 架构无法利用 SIP、BEEP 和 XMPP 这样的消息传递协议,因为 Java EE 的同步 API 持续使用单个线程。由于应用服务器使用有限的线程池,持续使用一个线程将使应用服务器在使用这些协议发送和接收消息时无法处理其他请求。同样要注意,使用这些协议发送的消息可长可短(尤其在使用 BEEP 时),并且要生成这些消息,还需要使用 Web 服务或其他方法访问部署在其他组织内的资源。此外,BEEP 和 Stream Control Transmission Protocol (SCTP) 这样的传输协议在 TCP/IP 连接之上还需要建立一些同步的逻辑连接,这使线程管理问题变得更加严重。

  要实现流式场景,Web 应用程序必须摒弃标准的 Java EE 模式和 API。因此,Java EE 很少用于运行 P2P 应用程序或流视频。对于经常使用 Java Connector Architecture (JCA) 连接器实现专有异步逻辑的协议,常常开发自定义组件来处理(正如后文将介绍的,新一代 servlet 引擎也支持使用非标准接口处理 Comet 模式。然而,就 API 和使用模式而言,这种支持与标准的 servlet 接口截然不同)。

  最后,回想一下 Java EE 的一个基本原理,即对网络基础结构进行优化可以缩短事务持续时间。但是,对于现场直播的视频提要,提升网络基础结构的速度丝毫不会减少请求的持续时间,因为视频流是边生成边发送给客户机的。对网络基础结构进行优化只会增加流的数量,从而支持更多的客户机并以更高的分辨率处理流。

0
相关文章