扫盲贴 - J2EE集群之释疑

转载:http://hqman.iteye.com/blog/92684,虽然是一篇很老的文章对于小白还是有很大的阅读价值。

对于理解J2EE集群技术不错的文章,虽然是Sun的技术人员撰写的,基本观点还算客观,内容深浅恰当,非常适合刚刚接触集群的朋友阅读,故此大胆翻译过来,放在这里和大家共享,错误难免,欢迎指正。
原链接
Uncover the hood of J2EE Clustering

 

===================================================================================

7 关于J2EE集群的神话

7.1 失效转移可以完全避免错误。  ---否定

JBoss文档中,有一整章节警告“你真的需要HTTP会话复制吗?”,是的,有时候一个没有失效转移的高可用性方案也是可以接受的,并且便宜。更进一步说,失效转移并不像你想的那样有力。

到底失效转移给了你什么?你们中的一些可能认为它可以避免错误。您瞧,没有失效转移,会话数据在服务器失效时丢失了并引起错误;当会话失效转移,会话可以从备份中恢复,并且请求可以由另一个实例继续处理,客户端不知道该失效。这可能是真的,但它不是必要的条件。

当我定义“失效转移”时,我定义了失效转移发生的条件:“在方法调用之间”,意味着你可以有两个连续的到一个远程对象的方法,失效转移将发生在第一个方法成功完成之后和第二个方法请求发出之前。

那么,在方法调用处理中间,远程服务器失效了会发生什么事情?答案是:处理将停止,大多数案例中,客户端将看到错误信息,除非该方法是等幂的(参考前文)。如果是等幂方法,一些负载均衡器足够聪明,会在其它服务器上重试这些方法。

为什么等幂重要?因为当失效发生时,客户端从来不知道请求在哪里执行,方法被初始化或已经完成了?客户端从不确定它。如果方法不是等幂的,两次调用同样的方法将改变系统状态两次,系统将处于不一致状态。

您可能想把所有的方法放在一个事务中就变成等幂的了。毕竟,如果错误发生,事务将回滚,所有的事务状态没有改变。但是事实是,事务边界不能包括所有远程方法调用。如果事务提交,在返回客户端时网络崩溃,客户端不会知道服务器事务成功与否。

在应用中,将所有方法变成等幂是不可能的。所以,通过失效转移,你可以减少错误,但不能避免它们!以再现购物网站为例,假定每台服务器实例可以同时处理 100个在线用户的请求。当一台服务器失效,没有会话失效转移的方案将丢失所有那100个用户的会话数据并激怒他们;当拥有会话失效转移,只有20个用户 的请求被失效的服务器在处理过程中,只有这些用户被错误激怒了。其它80个用户还处在思考时间(用户行为的间隔时间)或者方法调用之间。这些用户的会话被 透明地失效转移了。所以,你应该考虑以下事项:

*激怒20个和100个用户的不同影响
*拥有失效转移和没有失效转移的成本

7.2 单机应用可以被透明地转换为集群结构 ---- 绝对不是!
虽然一些提供商声称他们的J2EE产品的适应性,不要相信他们!实际上,你应该在系统设计开始时就考虑集群,并影响到开发和测试的所有阶段。

7.2.1 Http会话
在集群环境,对HTTPSession的使用有着严格的限制正如我在前边提及的一样,你的应用服务器依赖不同的机制使用会话失效转移。最重要的限制是所有 存储在HTTPSession里的对象必须是可序列化的,这一点限制了应用的结构和设计。一些设计模式和MVC框架使用HTTPSession存储不可序 列化对象(如Servlet Context,Local EJB 接口,web services引用),这样的设计不能在集群中工作。其次,对象序列化和反序列化在性能上消耗很大特别是数据库方案。在这样的环境中,存储巨大或众多的 会话对象,应该避免。如果你已经选择内存复制方案,小心HTTPSession的交叉引用属性的限制。另一主要的区别是,你需要在每次改变 HTTPSession属性的时候调用“setAttribute ()”方法。调用这些方法在单机应用中不是必须的。其目的是将改变的属性和未改变的属性分离开来,所以系统可以只备份必要的数据。

7.2.2 缓冲
几乎我经历过的每一个J2EE项目都使用缓冲提升性能,所有的流行服务器提供不同程度的缓冲以提升应用性能。但这些缓冲是单机应用的典型设计,只能在一个 JVM实例上工作。我们需要缓冲是因为创建这些新对象的代价是如此昂贵,所以我们维护一个对象池来重用对象实例。每个JVM实例都拥有自己的缓冲拷贝,它 们也应该被同步,以在所有服务器实例上维持一致的状态。有时,这种同步导致性能恶劣还不如不要缓冲。

7.7.3 静态变量
一些设计模式,比如“Singleton”(单例) 使用静态变量来给其它对象共享状态。这种方案在单一的服务器上工作得很好,但在集群中失效了。集群中的每个实例都会在其JVM实例中维护它自己的静态变量 拷贝,因此就破坏了该设计模式的共享机制。一个使用静态变量的例子是保持在线用户的总数。简单的办法就是将改数字存储到静态变量中,当用户登录或下线时增 加或减少它。在单一服务器上该应用绝对运行得非常好,但在集群中就失效了。更可取的办法是将所有状态存储到数据库中去。

7.7.4 外部资源
虽然J2EE规范不推荐使用,外部I/O操作还是有很多的用途。例如一些应用使用文件系统存储用户上载的文件,或者创建动态的配置XML文件。在集群中, 英勇服务器没法跨实例复制这些文件。为了在集群中工作,解决方案是如有可能,使用数据库替代外部文件。也可以选择SAN作为*文件存储。(备注:SAN 英文全称:Storage Area Network,即存储区域网络。它是一种通过光纤集线器、光纤路由器、光纤交换机等连接设备将磁盘阵列、磁带等存储设备与相关服务器连接起来的高速专用 子网。)

7.7.5 特殊的服务
有一些特殊的服务只有在单机模式下才有意义。定时器服务就是一种,给予一个恒定的间隔有规律地发生。定时器服务通常用来自动执行管理任务,比如日志文件转 储,系统数据备份,数据库consistence 检测和冗余数据清除。一些基于事件的服务也很难移植到集群环境中。初始化服务就是很好的例子。邮件通知服务也是如此。

这些服务由事件而非请求触发,应当只执行一次。这样的服务将使得集群的负载均衡和失效转移的意义降低。

一些产品对这样的服务早有准备,例如,JBoss使用“集群单一设施”协调所有实例,保证只执行这些服务一次或仅仅一次。基于你选择的产品平台,这些服务有可能成为移植到集群的障碍。

7.8 分布式结构比排列式结构更有弹性? -- 不一定!
J2EE技术,特别是EJB,因为分布式计算而产生。解耦业务功能,重用远程对象使得多层应用流行。但我们也不能把所有东西都分布式化吧。一些J2EE架构师认为将web层和EJB层紧密排列更好。
扫盲贴 - J2EE集群之释疑
图20:分布式结构

如图20分布式结构,当请求到来时,负载均衡器将它们分发到不同的服务器上的web容器,如请求中包括EJB调用,web容器将重新分发EJB调用到布通的EJB容器。这样,请求被负载均衡和失效转移了两次。

一些人不看好分布式结构,他们指出:

*第二次负载均衡是不必要的,因为它不能使任务分配更均匀。每个服务器实例在同一个JVM实例中都拥有它自己的web容器和EJB容器。让EJB容器处理其它实例的web容器的请求,看不出比实例内部调用有更多的优点。

*第二次失效转移是不必要的,因为它并不增加可用性。多数提供商的产品都是在同一JVM实例中集成了web容器和EJB容器。如果EJB容器失效,在多数情况下,web容器此时也是失效的。

*性能降低了。设想应用中的一个方法将调用几个EJB,若对每个EJB进行负载均衡,最终应用实例跨越了很多的服务器实例运行。这些服务器对服务器的横跨通信是不必要的。还有,如果方法在一个事务中,事务边界将包括许多服务器实例,严重影响了性能。

在实际的运行状态,多数提供商(包括Sun JES, Weblogic and JBoss)优化了EJB负载均衡使得请求首先选择在同一个服务器中的EJB容器。用这种办法,只在web层进行负载均衡,后续的服务都在同一服务器上处 理。这种结构称为排列式结构。技术上说,也是分布式结构的一种。
扫盲贴 - J2EE集群之释疑
图2:排列式结构

一个有趣的问题是,因为大部分发布运行时最后都成为了排列式结构,为什么不直接使用本地接口代替远程接口,这将提升性能。当然可以这样。但请记住,使用本 地接口,web组件和EJB就紧密耦合了,使得方法直接调用而非通过IIOP/RMI。负载均衡器和失效转移分发器没有机会拦截本地调用,“Web+ EJB”过程就被作为一个整体了。

不幸的是,集群中,在J2EE服务器上使用本地接口有很多限制。EJB是带有本地接口的本地对象,但他们不可序列化。限制就是本地引用不允许存储在 HTTPSession中。一些产品,如Sun JES区别处理本地EJB,使他们可序列化也能存储在HTTPSession中。

另一个有趣的问题是:因为排列式结构很流行也有良好的性能,为什么还需要分布式结构?大多苏h情况,事出有因,有时分布式结构不可替代。

*EJB不仅仅给web容器使用,富客户端也是用户之一。

*EJB组件和web组件可能在不同的安全级别,需要物理地分隔开来。所以,防火墙可能用来保护运行EJB的更重要的机器。

*Web层和EJB层的极端不对称也许是选择分布式结构的一个好理由,例如,一些EJB组件太复杂资源消耗巨大,那么它们只能在一些昂贵的 大服务器上运行;另一方面,web组件(HTML,JSP,Servlet)非常简单可以在便宜的PC服务器上运行。在这种条件下,专门的web服务器接 收客户端请求,提供静态数据(HTML和图片)和简单的web组件(JSP和Servlet)。大型服务器只用来进行复杂计算。

8 结论
集群和单机环境是不同的。J2EE提供商以不同的方式实现集群。为了构建一个大型的系统,在项目开始时,你就应该为J2EE集群做准备。选择合适的 J2EE产品是g和你的应用。选择合适的第三方软件和框架时确保它们可以被集群。然后设计合适的架构以得到集群带来的实际利益。

 

-----------------------------------------------------------------------------------------------------------------------------------

Weblogic集群概念

ØDomain:由配置为Administrator Server的WebLogic Server实例管理的逻辑单元,这个单元是有所有相关资源的集合。

ØServer: 一个相对独立的,为实现某些特定功能而结合在一起的单元。按功能可分为domain server 和managed server。一个Domain 可以包含一个或多个WebLogic Server实例,甚至是Server集群。一个Domain中有一个且只能有一个Server 担任管理Server的功能,其它的Server具体实现一个特定的逻辑功能。

ØDomain  Server:在一个集群中,有且仅有一个domain server,即管理server,该server只负责管理多个Managed server(被管理server),即domain server仅仅是行政领导,考勤之类的活动,如某个managed Sever的状态,是未知(unKnown),还是运行(run),还是停止(shutdown),远程启动等等,不负责具体业务。因此部署时domain server上不要部署具体任务,毕竟人家是当官的吗。

ØManaged  Server:真正的实干家,部署具体的应用。应用及业务逻辑组件被分发在多个受管服务器(Managed Server)

Weblogic集群要求

Ø集群中的所有Server必须位于同一网段,并且必须是IP广播(UDP)可到达的

Ø集群中的所有Server必须使用相同的版本,包括Service Pack

Ø集群中的Server必须使用永久的静态IP地址。动态IP地址分配不能用于集群环境。如果服务器位于防火墙后面,而客户机位于防火墙外面,那么服务器必须有公共的静态IP地址,只有这样,客户端才能访问服务器 

Ø使用weblogic的支持集群的licence