背景技术
JavaEE是当前主流的商业应用系统开发平台,该技术提供了一个基于组件的方法来设计、开发、装配和部署企业级应用程序。具体而言,JavaEE定义了整个标准的应用开发体系结构和一个部署环境,应用开发者开发时只要专注于具体商业逻辑和商业业务规则的实现上,而其他的诸如事务、持久化、安全等系统开发问题可以由应用程序容器或者服务器处理,开发完成后,就可以方便地部署到实现规范的应用服务器中。采用JavaEE这种多层结构的分布式的应用程序模型,可以更快地开发和发布的新的应用解决方案。
在JavaEE中,Enterprise Java Beans(EJB)是JavaEE平台规范中定义的一种组件模型,用于对分布式企业应用中的业务逻辑进行封装。使用EJB技术开发业务组件,可以提高应用的开发、维护的效率,同时,也将提高应用的可移植性及可靠性。应用开发人员可以更专注于特定的业务需求与模型。现有技术中,EJB可以分为会话Bean(Session Bean)、实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)。
其中,Session Bean用于实现业务逻辑,它可以是有状态的(stateful),也可以是无状态的(stateless)。有状态会话Bean(SFSB)会保存客户端的状态,而无状态会话Bean(SLSB)不会专门保存客户端的状态。每当客户端请求时,容器就会选择一个Session Bean来为客户端服务。SessionBean可以直接访问数据库,但更多时候,它会通过Entity Bean实现数据访问。
Entity Bean是域模型对象,用于实现O/R映射,负责将数据库中的表记录映射为内存中的Entity对象,事实上,创建一个Entity Bean对象相当于新建一条记录,删除一个Entity Bean会同时从数据库中删除对应记录,修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步。
MessageDriven Bean是EJB2.0中引入的新的企业Bean,它基于JMS消息,只能接收客户端发送的JMS消息然后处理。MDB实际上是一个异步的无状态Session Bean,客户端调用MDB后无需等待,立刻返回,MDB将异步处理客户请求。这适合于需要异步处理请求的场合,比如订单处理,这样就能避免客户端长时间的等待一个方法调用直到返回结果。
作为网络上的商业应用系统,同时访问的人数是很多的,在大量访问的情况下,过多的资源请求和有限的服务器资源之间就会出现矛盾,当单一的服务器不能同时服务过多数量的用户时,就需要搭建一个服务器集群,以提升系统的吞吐量。
参考图1,示出了一种典型的集群环境的结构示意图,其中,多台web server组成了一个web集群,多台EJB server组成了EJB集群。用户在访问系统时,不会感觉到集群的存在,而仅知道自己在访问一个系统,例如,对一个http://server/app/foo.jsp的URL进行访问,在这种情况下,集群内部会根据各服务器的负载状况将该用户的请求分发到其中一台服务器上进行响应。然而,在集群内部的某一台服务器可能会出现由于不能负载而导致崩溃的情形,如果这台服务器正在响应相应的用户请求,则会导致响应失败,为不影响用户的使用体验,使用户感觉不到其中的变化,则需要在集群内部恢复该用户的请求。
如果当前企业应用系统是采用JavaEE技术开发的,并使用了SFSB保存了用户与服务器的会话状态,则需要解决的是,集群的SFSB失败恢复的问题。现有的解决方法是采用内存复制技术,即在集群的内部服务器之间进行内存复制,例如,将A服务器中的SFSB状态复制到B服务器中,这样,在B服务器中就有了A服务器中SFSB的备份,一旦A服务器不能响应用户请求,则由B服务器来接管对A服务器SFSB的请求进行处理。
然而,在采用内存复制技术的EJB集群中,由于集群内部需要不停地相互复制SFSB的状态,由于这些状态的传输会占用带宽,从而导致集群内部的资源占用过多,系统负担较大,严重情况下,还可能形成网络风暴;并且,大量的SFSB状态的复制还会影响其它功能模块正常使用网络带宽,对整个系统的健康状态产生了负面的影响,比如降低了集群的响应速度,然而,如果加大硬件投资,增加网络带宽,又会过多增加成本及各种相关开销。
所以,本领域技术人员迫切需要发展一种能在有效节约成本的前提下,降低系统负担和资源占用,提高EJB集群失败恢复处理效率的方法和装置。
发明内容
本发明所要解决的技术问题是提供一种EJB集群的失败恢复处理方法,用以在有效节约成本的前提下,降低系统负担和资源占用,提高EJB集群失败恢复处理效率。
本发明还提供了一种EJB集群的失败恢复处理系统,用以保证上述方法在实际中的实现及应用。
为了解决上述问题,本发明公开了一种EJB集群的失败恢复处理方法,包括:
在客户端加载EJB业务接口的存根,所述存根记录有当前EJB业务组件在客户端缓存的会话状态数据和目标服务器地址;
所述存根依据所述目标服务器地址向目标服务器发送调用请求;
所述目标服务器分析所述调用请求,若所述调用请求涉及有状态会话bean的调用,且所述目标服务器位于EJB集群中,则提取所述会话状态数据,并获得所述会话状态数据的会话ID;
依据所述会话ID获取当前业务组件实例的上下文,并依据所述会话状态数据更新所述目标服务器缓存中所述业务组件实例上下文中的会话状态数据;
加载EJB业务接口的服务器端桩,所述服务器端桩记录有相应业务组件的调用方法;
依据所述缓存中的会话状态数据更新所述业务组件实例;
由所述服务器端桩调用相应的方法处理所述业务组件实例,生成业务逻辑的返回值和会话状态数据的更新值;
客户端接收所述业务逻辑的返回值和会话状态数据的更新值,并依据所述会话状态数据的更新值更新所述客户端缓存的会话状态数据。
优选的是,通过以下步骤加载客户端的存根:
通过JNDI服务,获得EJB Home接口的客户端实现;
调用所述EJB Home接口的Create方法,获得EJB业务接口的存根。
本发明实施例还公开了一种EJB集群的失败恢复处理系统,包括:
客户端、通讯模块和服务器,
所述客户端包括:
加载模块,用于在客户端加载EJB业务接口的存根,所述存根记录有当前EJB业务组件在客户端缓存的会话状态数据和目标服务器地址;
存根:用于依据所述目标服务器地址向目标服务器发送调用请求;
客户端缓存更新模块,用于接收业务逻辑的返回值和会话状态数据的更新值,并依据所述会话状态数据的更新值更新所述客户端缓存的会话状态数据;
所述通讯模块用于在客户端与服务器之间进行通讯;
所述服务器包括:
请求处理模块,用于分析所述调用请求,若所述调用请求涉及有状态会话bean的调用,且所述目标服务器位于EJB集群中,则提取所述会话状态数据,并获得所述会话状态数据的会话ID;
服务器缓存更新模块,用于依据所述会话ID获取当前业务组件实例的上下文,并依据所述会话状态数据更新所述目标服务器缓存中所述业务组件实例上下文中的会话状态数据;
桩加载模块,用于加载EJB业务接口的服务器端桩,所述服务器端桩记录有相应业务组件的调用方法。
实例更新模块,用于依据所述缓存中的会话状态数据更新所述业务组件实例;
服务器端桩:用于调用相应的方法处理所述业务组件实例,生成业务逻辑的返回值和会话状态数据的更新值。
优选的是,所述客户端的加载模块进一步包括:
JNDI查找子模块,用于通过JNDI服务,获得EJB Home接口的客户端实现;
存根获得子模块,用于调用所述EJB Home接口的Create方法,获得EJB业务接口的存根。
与现有技术相比,本发明具有以下优点:
本发明通过在客户端加载SFSB的存根(Stub),当在客户端调用SFSB时,实际上是委派给Stub类完成的。Stub类中保存着服务器端SFSB实例的会话状态数据,当调用发生时,Stub类与服务器端通信,将要调用的方法、参数值随同会话状态数据一并发送给服务器端,服务器端接收到调用请求后,会将客户端发来的会话状态数据跟服务器端的会话状态数据进行同步处理,并在真正调用SFSB之前,更新其会话状态数据,在调用完成之后,服务器端又将调用返回值随同会话状态数据更新值一并发送给客户端,使得客户端始终保存着最新的会话状态数据。因此,本发明不需要在内存中不停复制SFSB的状态,减少了集群内部的资源占用,降低了系统负担,从而有效节约了成本;再者,应用本发明实施例,当某个服务器出现问题时,客户端会带着原服务器上的组件会话状态去访问集群中的另一台服务器,从而保证了会话失败恢复的处理效率,同时又避免了服务器端的网络风暴。
具体实施方式
为使本发明的上述目的、特征和优点能够更加明显易懂,下面结合附图和具体实施方式对本发明作进一步详细的说明。
本发明可用于众多通用或专用的计算系统环境或配置中。例如:个人计算机、服务器计算机、手持设备或便携式设备、平板型设备、多处理器系统、包括以上任何系统或设备的分布式计算环境等等。
本发明可以在由计算机执行的计算机可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本发明,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。
参考图2,示出了一种EJB集群的失败恢复处理方法实施例1的流程图,可以包括以下步骤:
步骤201、在客户端加载EJB业务接口的存根(Stub),所述存根记录有当前EJB业务组件在客户端缓存的会话状态数据和目标服务器地址;
步骤202、所述存根依据所述目标服务器地址向目标服务器发送调用请求;
步骤203、所述目标服务器分析所述调用请求,若所述调用请求涉及有状态会话bean(SFSB)的调用,且所述目标服务器位于EJB集群中,则提取所述会话状态数据,并获得所述会话状态数据的会话ID;
有状态会话Bean(SFSB)表示一个特定客户端的会话状态的对象。例如,会话对象在客户端多次调用之间自动维持它们的会话状态。一个SFSB有一个方法来初始化自己(例如,在EJB2.1中是通过ejbCreate()来实现的;在EJB3.0的规范中可以通过自定义方法完成,并把它们暴露在业务接口中。)
步骤204、依据所述会话ID获取当前业务组件实例的上下文,并依据所述会话状态数据更新所述目标服务器缓存中所述业务组件实例上下文中的会话状态数据;
步骤205、加载EJB业务接口的服务器端桩(skeleton),所述服务器端桩记录有相应业务组件的调用方法;
步骤206、依据所述缓存中的会话状态数据更新所述业务组件实例;
步骤207、由所述服务器端桩调用相应的方法处理所述业务组件实例,生成业务逻辑的返回值和会话状态数据的更新值;
步骤208、客户端接收所述业务逻辑的返回值和会话状态数据的更新值,并依据所述会话状态数据的更新值更新所述客户端缓存的会话状态数据。
Enterprise JavaBeans(EJB)是一个开发和部署分布式服务器端的、带事务处理的、安全的商业组件的规范和结构。EJB的体系结构是J2EE的基础和核心,J2EE定义了整个标准的应用开发体系结构和一个部署环境。在这个体系结构中,应用开发者的注重力集中在封装商业逻辑和商业规则上,一切与基础结构服务相关的问题和底层分配问题都由应用程序容器或服务器来处理。甚至,从属于事务、持久化、安全等等方面的应用组件的运行时属性都可以使用高度灵活的声明方法在部署的环境中定制。这个体系结构定义了一个容器和一个服务器模型--容器是应用组件生存和执行的环境,而这个容器却又借居在一个服务器之中。
EJB规范定义了一些标准,例如:
1、EJB服务器提供商提供在分布式事务处理、系统服务等方面的应用服务器。
2、EJB容器提供商提供EJB组件实例运行环境和部署工具。
服务器/容器提供商是典型的操作系统开发商、数据库开发商或者是应用服务器开发商。
3、Bean的提供商或者EJB开发者开发的EJB组件都包含商业逻辑及商业功能。EJB开发者提供的每一个EJB组件都应满足以下条件:EJB的实现中应包括所有必须有的组件-容器合同方法(Contract method),如:ejbCreate(),ejbRemove()等等和一些商业方法(business method);Home接口;Remote接口;在需要的情况下还应当有帮助类。Home接口为创建、删除和查找EJB实例的方法提供签名,Remote接口定义了商业方法的签名。
4、应用程序组装器把一些由Bean提供商开发的EJB组件组装成一个完整的J2EE应用程序。
5、部署器在应用服务器中安装应用组件并配置它们的事务、持久化和安全方面。以便于处理复杂问题,诸如:事务处理、并发处理、持久化以及安全。
在基于EJB的事务处理中,EJB组件是为企业级应用设计的Java组件模型,是基于标准分布式对象技术、CORBA和RMI的服务器端java组件。EJB组件总是分布式的,提供了应用的商务逻辑部分。由于它们不涉及表示层的问题,因此必须与其它的显示技术(如servlets),服务于Html客户端的jsp技术,或者使用了诸如AWT、Swing技术的java应用一起使用。EJB服务器是管理EJB容器的高端进程或应用程序,并提供对系统服务的访问。EJB服务器也可以提供厂商自己的特性,如优化的数据库访问接口,对其他服务(如CORBA服务)的访问,对SSL 3.0的支持等。一个EJB服务器提供对可访问JNDI的名字服务和事务服务支持。一些可能的EJB服务器的例子如:数据库服务、应用服务器、中间件服务器等。EJB容器是一个管理一个或多个EJB类/实例的抽象。它通过规范中定义的接口(如Home接口、远程接口)使EJB类访问所需的服务。
优选的是,在本实施例中,所述步骤201可以包括以下子步骤:
子步骤A1、通过JNDI服务,获得EJB Home接口的客户端实现;
子步骤A2、调用所述EJB Home接口的Create方法,获得EJB业务接口的存根。
具体而言,由于Home接口列出了所有定位、创建、删除EJB类实例的方法,因而可以使用enterprise bean的客户端通过它的home接口创建它的实例。Home接口包含一个或多个用来创建enterprise bean实例的create()方法。这个home接口通过称为home object的类来实现。一个home object的实例在服务器中实例化,使得客户端可以访问它们。定位home object一个home object的引用被放在名字服务中,客户端能通过JNDI访问它。EJB服务器一般提供某种名字空间的实现,虽然有时可以使用外部的名字空间。然而这两种情况下客户端都必须知道名字空间的位置以及JNDI的上下文类。例如,一个客户端的Applet可以接收名字空间和JNDI上下文类作为applet的参数。
参考图3,示出了一种EJB集群的失败恢复处理方法实施例2的流程图,可以包括以下步骤:
步骤301、通过JNDI查找得到EJB Home接口的客户端实现;
由于EJB组件通过命名服务注册到JNDI服务器中,所以,客户端首先通过JNDI服务,得到EJB Home接口的客户端实现;
步骤302、调用Home接口的Create方法,得到EJB业务接口的客户端存根(Stub);
在实际中,所述Stub类可以是应用服务器动态生成的,它实现了EJB的业务接口。
步骤303、调用EJB业务接口的实现方法;
本步骤实际上调用的是Stub上的实现。
步骤304、从Stub中取出当前EJB组件在客户端缓存的会话状态数据和目标服务器的地址;
步骤305、Stub确认目标服务器通信正常,于是向目标服务器发送调用请求,否则,将选择集群内的另一个目标服务器;
上述步骤301-304都在客户端执行,通过步骤305,执行主体转移到服务器端。
步骤306、服务器收到客户端发出的调用请求,分析出当前调用是否涉及有状态会话bean(SFSB)的调用,并且服务器当前位于一个EJB集群内,如果是,则取出客户端请求中的会话状态数据,并获得该会话状态数据的会话ID;
步骤307、依据所述会话ID获取当前业务组件实例的上下文,并依据所述会话状态数据更新所述目标服务器缓存中,所述业务组件实例上下文中的会话状态数据;
步骤308、调用EJB业务接口的服务器端桩(Skeleton);
Skeleton也可以由应用服务器动态生成,可用于判断具体调用业务组件的哪一个方法;
步骤309、调用EJB业务接口的服务器端实现;
步骤310、取出步骤307缓存的会话状态数据,更新真正的业务组件域;
其中,真正的业务组件是指EJB组件开发者实现的完成业务逻辑的类)。
步骤311.调用真正的业务组件的相应方法,并完成业务逻辑计算,获得业务逻辑计算的返回值和会话状态数据的更新值;
步骤312、将业务逻辑计算的返回值和会话状态数据的更新值发送给客户端;
步骤313、客户端接收服务器发送的业务逻辑计算的返回值和会话状态数据的更新值,将返回值赋值给客户端程序,将会话状态数据更新到Stub的缓存中。
可以看出,在本实施例中,客户端具有SFSB的存根(Stub),当在客户端调用SFSB时,实际上是委派给Stub类完成的。Stub类中保存着服务器端SFSB实例的会话状态数据,当调用发生时,Stub类通过socket或其它方式与服务器端通信,并将要调用的方法、参数值随同会话状态数据一并发送给服务器端,服务器端接收到调用请求后,会将客户端发来的会话状态数据跟服务器端的会话状态数据进行同步处理,并在真正调用SFSB之前,更新其会话状态数据,在调用完成之后,服务器端又将调用返回值随同会话状态数据更新值一并发送给客户端,使得客户端始终保存着最新的会话状态数据,因此,即使原来对其进行服务的服务器出现问题,也不会导致会话状态数据丢失的问题。
需要说明的是,对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本发明并不受所描述的动作顺序的限制,因为依据本发明,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作和模块并不一定是本发明所必须的。
采用现有的内存复制技术,在处理EJB集群的失败恢复时,通过在集群的内部服务器之间进行内存复制,例如,将A服务器中的SFSB状态复制到B服务器中,这样,在B服务器中就有了A服务器中SFSB的备份,一旦A服务器不能响应用户请求,则由B服务器来接管对A服务器SFSB的请求进行处理。由于集群内部需要不停地相互复制SFSB的状态,由于这些状态的传输会占用带宽,从而导致集群内部的资源占用过多,系统负担较大,严重情况下,还可能形成网络风暴;并且,大量的SFSB状态的复制还会影响其它功能模块正常使用网络带宽,对整个系统的健康状态产生了负面的影响,比如降低了集群的响应速度,然而,如果加大硬件投资,增加网络带宽,又会过多增加成本及各种相关开销。
而应用本发明实施例,在EJB集群内部,即在A服务器和B服务器之间,不再进行内存复制。而在SFSB的客户端,缓存SFSB实例A的状态数据,当A服务器出现通讯或其它故障时,客户端则可以带着A服务器上的SFSB A的状态访问B服务器。也就是说,客户端保存有SFSB的存根,并保存着服务器端组件的会话状态,当这个服务器出现问题时,客户端会带着原服务器上的组件会话状态去访问集群中的另一台服务器,从而保证了会话失败恢复的处理效率,同时又避免了服务器端的网络风暴。
参考图4,示出了本发明的一种EJB集群的失败恢复处理系统实施例的结构框图,可以包括:
客户端41、通讯模块42和服务器43,
所述客户端41包括:
加载模块411,用于在客户端加载EJB业务接口的存根412,所述存根记录有当前EJB业务组件在客户端缓存的会话状态数据和目标服务器地址;
存根412:用于依据所述目标服务器地址向目标服务器发送调用请求;
客户端缓存更新模块413,用于接收业务逻辑的返回值和会话状态数据的更新值,并依据所述会话状态数据的更新值更新所述客户端缓存的会话状态数据;
所述通讯模块42用于在客户端与服务器之间进行通讯;
所述服务器43包括:
请求处理模块431,用于分析所述调用请求,若所述调用请求涉及有状态会话bean的调用,且所述目标服务器位于EJB集群中,则提取所述会话状态数据,并获得所述会话状态数据的会话ID;
服务器缓存更新模块432,用于依据所述会话ID获取当前业务组件实例的上下文,并依据所述会话状态数据更新所述目标服务器缓存中所述业务组件实例上下文中的会话状态数据;
桩加载模块433,用于加载EJB业务接口的服务器端桩,所述服务器端桩记录有相应业务组件的调用方法。
实例更新模块434,用于依据所述缓存中的会话状态数据更新所述业务组件实例;
服务器端桩435:用于调用相应的方法处理所述业务组件实例,生成业务逻辑的返回值和会话状态数据的更新值。
优选的,在本实施例中,所述客户端的加载模块411可以进一步包括:
JNDI查找子模块,用于通过JNDI服务,获得EJB Home接口的客户端实现;
存根获得子模块,用于调用所述EJB Home接口的Create方法,获得EJB业务接口的存根。
对于图4所示的系统实施例而言,由于其基本相应于图2和图3所示的方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
以上对本发明所提供的一种在容器中装载组件的方法及一种在容器中装载组件的装置进行了详细介绍,本文中应用了具体个例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。