Java EE集群技术初探——第七部分(EJB集群的实现)

 
EJB 集群的实现
EJB Java EE 重要的组成部分,实现 EJB 的集群也是最具挑战的部分。
 
EJB 技术也来源于分布式计算,可在独立的服务器上运行。 Web 服务器组件或胖客户端能从其他计算机通过标准 RMI/IIOP 协议访问 EJB 组件。调用远程 EJB 的方法和调用本地 Java 对象的方法一样。实际上, RMI-IIOP 完全实现了对本地 / 远程调用的透明性。
上图展示了调用远程 EJB 的机制。当客户端要调用 EJB 时,不能直接调用 EJB ,它需要调用称为 存根 (stub)” 的本地对象,其接口与远程对象一致,充当着远程对象代理作用。 Stub 负责本地接收方法调用并将其传递到网络另一端的远程 EJB 上去。 Stub 在客户端 JVM 中运行,并通过 RMI/IIOP 向远程网络查找真实对象。
 
我们通过了解如何在代码中调用 EJB 来解释 EJB 集群的实现。如欲调用 EJB ,需要:
  • JNDI服务器中查找EJBHome存根。
  • 通过EJBHome存根查找或创建EJB对象,返回EJBObject存根。
  • 通过EJBObject存根调用EJB方法。
 
负载均衡和失败转移可在 JNDI 查找的时候发生。当通过 EJB 存根 ( 无论 EJBHome 还是 EJBObject) 调用方法时,厂商已通过不同的方法实现了 EJB 的负载均衡和失败转移。
 
智能存根
由于客户端通过存根对象访问远程 EJB ,存根对象可通过检索 JNDI 树获得,甚至可能让客户端透明地通过下载任意一台 web 服务器上的类文件也可获得。所以,存根的特点有:
 
存根可以在运行时动态地或通过编程的手段生成。存根的定义,即类文件并不需要在客户端环境的 classpath 下,也不需要包含在客户端运行时的 JAR 包中 ( 因为可通过下载的方法获得 )
如上图, BEA WebLogic JBoss 采用在存根代码中添加特定功能来实现 EJB 的集群。这些代码透明运行在客户端。这种技术称之为智能存根技术。
 
智能存根之所以智能是因为它包含了能访问的目标实例。它能侦测到目标实例的失败,并使用复杂的负载均衡和失败转移的逻辑将请求转发至其他目标。此外,如果集群的拓扑图发生了变化 ( 例如,有新实例加入或实例移除 ) ,存根能自动更新目标列表来反映最新的变化情况。
 
在存根中实现集群的优点如下:
  • 因为EJB存根运行在客户端,所以节省了很多服务器端的资源。
  • 负载均衡器整合在了客户端代码中,并与客户端生命周期息息相关。这就避免了单点负载均衡器失败的情况。如果负载均衡器失败了,客户端也极有可能失败,所以对系统并没有太大影响。
  • 存根能自动动态下载更新,最大程度降低了维护量。
 
IIOP 运行时库
Sun JES 应用服务器通过另一途径实现 EJB 集群。负载均衡和失败转移逻辑在 IIOP 运行时库中实现。例如, JES 修改了 ORBSocketFactory 的实现,让其支持集群,如下图。
修改过的 ORBSocketFactory 拥有执行负载均衡和失败转移的所有逻辑和算法,同时也保持了存根的简洁。因为实在运行时库中实现的,所以比起在存根中实现的办法来说它能更容易获取系统资源。但是这种方法在客户端需要指定的运行库,在与别的 Java EE 产品整合时可能会有一些麻烦。
 
 
监听代理 (Interceptor Proxy)
IBM WebSphere 引入了位置服务后台线程 (LSD Location Service Daemon) ,其作为 EJB 客户端的监听代理,如下图所示。
在这种方法中,客户端从 JNDI 中查找并获得存根。存根包含了通向 LSD 的路由信息而不是直接到 EJB 驻留的应用服务器。 LSD 接收所有的请求并根据负载均衡和失败转移策略来决定将它们分别发送至哪台实例中。本方法使集群的安装和维护工作量加大。
 
 
EJB 的集群支持
要调用 EJB 的方法,需要两种类型的存根对象:一个是 EJBHome 接口另一个是 EJBObject 接口。这就意味着对 EJB 的负载均衡和失败转移可能在两个阶段发生:
  • 当客户端使用EJBHome存根创建并查找EJB对象时
  • 当客户端使用EJBObject存根来调用EJB方法时
 
EJBHome 存根的集群支持
EJBHome 接口用来创建或查找在 EJB 容器中的 EJB 实例, EJBHome 存根是 EJBHome 接口的客户端代理。 EJBHome 接口不保持客户端的任何状态。所以,不同 EJB 容器的 EJBHome 接口对客户端来说都是相同的。当客户端调用 create() find() 方法时, home 存根根据负载均衡和失败转移算法从复制列表中选择一个服务器,并把对 home 接口的调用传递到那台服务器上。
 
EJBObject 存根的集群支持
EJBHome 接口创建 EJB 实例时,它将 EJBObject 存根返回客户端让用户调用 EJB 方法。系统已经有了一个集群中可用服务器的列表,在这些服务器上都部署了 EJB 组件,但是根据 EJB 的类型,不能将由 EJBObject 存根发起的方法调用发送至判断服务器实例的 EJBObject 接口。
 
无状态的会话 bean 是情况最简单的:正因为没有保存状态,所有 EJB 实例都可考虑为相同的,所以从 EJBObject 来的方法调用可被负载均衡或失败转移至任何参与的服务器实例上。
 
有状态的会话 bean 就不太一样了。有状态的会话 bean 需要保持特定客户端连续请求时的会话状态信息。总的来说,对有状态的会话 bean 实施集群和对 HTTPSession 实施集群差不多。通常, EJBObject 存根不会将请求转发至之前服务的实例之外的其他实例;它们通常会一直使用 EJBObject 创建时的实例,可以称之为 主实例 。在处理过程中,状态信息需要从主实例备份至其他服务器。如果主实例失败了,其他备份服务器将进行接管。
 
实体 bean 从根本上说还是无状态的,尽管它也处理有状态的请求。实体 bean 本身将所有信息数据备份至数据库中。感觉好像对于实体 bean 来说,负载均衡和失败转移都较容易实现。但实际上,实体 bean 不是总能得到负载均衡和失败转移的。正如设计模式中的建议,实体 bean 总是被包装在会话 bean 后。因此,大多数对实体 bean 的访问发生在正在处理的会话 bean 的本地接口中,而不是远程客户端。这就让负载均衡和失败转移失去了意义。
 
JMS 和数据库连接的集群支持
Java EE 中,除了 JSP Servlet JNDI EJB 之外还有其他的分布式对象。这些对象可能不能在集群实施中得到全面支持。
 
现在,一些数据库产品,例如 Oracle RAC Sybase SDC 支持集群环境并可部署成多点同步的数据库实例。但是, JDBC 是高度有状态的协议,其需要保存事务状态并紧密维护客户端和服务器的 socket 连接。所以,比较难实现集群。如果 JDBC 连接失败了,所有与连接相关的 JDBC 对象都会失败,而重新连接需要客户端代码的支持。 BEA WebLogic 使用 JDBC 连接池来降低重新连接的复杂度。
 
JMS 在大多数 Java EE 服务器中都支持,但不是完全支持。负载均衡和失败转移只在 JMS broker 上实现了,一些产品还支持 JMS 消息目的地的失败转移功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值