系统架构--揭开J2EE集群的神秘面纱(四)

6 EJB集群实现

EJB是J2EE技术中重要的部分,并且EJB集群是实现J2EE集群最大的挑战。

EJB技术是为分布式计算而生。它们可以在独立的服务器中运行。Web服务器组件或富客户端可以从其他的机器通过标准协议(RMI/IIOP)来访问EJB。你可以象调用你本地Java对象的方法一样调用远程EJB的方法。实际上,RMI/IIOP完全掩盖了你正在调用的对象是本地的还是远程的,这被称作本地/远程透明性。


图 16  EJB调用机制

上图显示了远程EJB的调用机制。当客户端想使用EJB,它不能直接调用,相反,客户端只能调用一个被称为“stub”的本地对象,它扮演了到远程对象代理的角色,并且有远程对象相同的接口。这个对象负责接受本地方法调用,并且这些调用通过网络代理到远程EJB。这些对象在客户JVM中运行,并且知道如何通过RMI/IIOP跨过网络查找真正的对象。要了解有关EJB更多的信息,请参考http://java.sun.com/products/ejb/

为解释EJB集群的实现,我们先看看在J2EE代码中如何使用EJB的。为了调用EJB,我们需要

  • 在JNDI服务器中查找EJBHome stub
  • 使用EJBHome stub查找或创建EJB对象,这样获得一个EJBObject stub
  • 在EJBObject stub上调用方法

负载均衡和失效转移可以在JNDI查找时发生,这我们已在上面阐述了。在EJB stub(包括EJBHome和EJBObject)的方法调用时,供应商采用以下三种方式实现EJB负载均衡和失效转移。

6.1 智能存根(Smart stub)
正如我们所知,客户端可以通过存根对象(stub)来访门远程的EJB,这个对象可以通过JNDI树获取,甚至客户端可能透明地从WEB服务器上下载存根类文件。

这样存根就可以在运行期动态地用程序生成,而其类文件也不必在客户端环境的classpath或库中。(因为它是可以被下载的)


图 17  智能存根

如图17所示,BEA WebLogic和Jboss通过在存根代码中组合几种行为来实现EJB集群,而这些都是在客户端透明运行的(客户端不需要了解这些代码)。这种技术叫做智能存根。

智能存根确实很聪明,它包含一组它可以访问的目标实例,可以检测这些实例的任何失效,它也包含了复杂的负载均衡和失效转移的逻辑,用来分发请求到目标实例。而且,如果集群拓朴改变了的话(比如新增或删除了服务器实例),存根可以更新它的目标实例清单来反映新的拓朴,而不需要手工重新配置。

使用智能存根实现集群有以下优点:

  • 因为EJB存根运行在客户端,所以它可以节省许多服务器资源。
  • 负载均衡是在客户端代码中,并且与客户端的生命周期相关。这样就消除了负载均衡器的单点失效。如果负载均衡器失效了,就意味着客户端也失效了,这种情况是能接受的。
  • 存根可动态的自动下载更新,这意味着零维护。

6.2 IIOP运行期库
Sun JES Application Server使用了另一种方法实现EJB集群。负载均衡和失效转移逻辑是在IIOP运行库中实现的。比如,JES修改了“ORBSocketFactory”的实现,使它能支持集群。如图18所示。


图 18  IIOP运行期

“ORBSocketFactory”的修改版有实现负载均衡和失效转移的所有逻辑和算法,这样就保持了存根干净和小。因为是在运行库中实现的,这样就比存根的方式更容易获得系统资源。但这种方式需要在客户端运行一个特殊的运行库,这样就给与其他J2EE产品进行互操作时带来了麻烦。

6.3 拦截器代理
IBM Webshpere采用了定位服务精灵(Location Service Daemon-LSD),它对EJB客户端扮演了拦截器代理的角色,如图19所示。


 

图 19  拦截器代理

在这种方式中,客户端通过JNDI查找获取存根,这个存根将信息路由到LSD,而不是运行了EJB的应用程序服务器。这样LSD接收到所有进来的请求,根据负载均衡和失效转移的策略来判断应该将它发送到哪个服务器实例。这种方式增加的安装和维护集群的额外的管理工作。

6.4 EJB的集群支持
要调用EJB的方法,要涉及到两种存根对象,一是EJBHome接口,另一个是EJBObject接口。这意味着EJB潜在的需要在两层上实现在负载均衡和失效转移。

  • 当客户端使用EJBHome存根创建或查找EJB对象时
  •  当客户端调用EJB对象上的方法时。

6.4.1 EJBHome存根支持集群

EJBHome接口用于在EJB容器中创建和查找EJB实例,而EJBHome存根是EJBHome接口的客户端代理。EJBHome接口不需维持任何客户端的状态信息。这样,来自不同EJB容器中的相同EJBHome接口对于客户端来说是一致的。当客户端执行create()或find()调用的时候,home存根根据负载均衡和失效转移算法从多个相同的服务器实例中选择一个,并将调用发送到该服务器的home接口上。

6.4.2 EJBObject存根支持集群

当EJBHome接口创建一个EJB实例,它将返回EJBObject的存根给客户端,并让用户调用EJB的业务方法。集群中已有一组可用的服务器实例,并在上面的部署了bean,但是不能将EJBObject存根对象向EJBObject接口发出调用转发到任意一个服务器实例上,这取决于EJB的类型。

无状态会话Bean是最简单的情况,因为不涉及到状态,所有的实例都可以认为是一样的,这样对EJBObject的方法调用可负载均衡和失效转移到任意一个服务器实例上。

集群的有状态会话Bean与无状态会话Bean有一点不同,正如我们所知,有状态会话Bean对于客户端连续的请求会持有状态信息。从技术上来说,集群有状态会话Bean与集群HTTP Session是一样的。在常规时间,EJBObject存根将不会把请求负载均衡到不同的服务器实例。相反,它将胶粘到最初创建的服务器实例上,我们称这个实例为“主实例”。在执行过程中,会话状态会从主实例备份到其他服务上去。如果主实例失效了,备份服务器将接管它。

实体Bean本质上是无状态的,尽管它可以处理有状态的请求。所有的信息都将通过实体Bean本身的机制备份到数据库中。这样看起来实体Bean可以象无状态会话Bean一样很容易获取负载均衡和失效转移。但实际,实体Bean多数情况下是不负载均衡和失效转移的。根据设计模式的建议,实体Bean被会话外观包装。这样,多数对实体Bean的访问都是进程内会话Bean通过本地接口完成的,而不是远程客户端。这使得负载均衡和失效转移没有意义。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值