呵呵,事情可能不是这个样子的……
如果有一台机器坏了,或者网络有问题,分发器还是继续将request发往那台坏的服务器,那么我们也就不需要session复制了,因为那将是毫无意义的。
别的app server怎么实现的我不知道,只能说一下weblogic的分发是怎么实现的:
1、实现请求的分发,可以靠硬件(高层交换机),也可以靠weblogic自己。一般的是新建一个proxy分发域,然后其中部署一个proxy应用,利用weblogic.servlet.proxy.HttpClusterServlet将请求分发到不同的server。
2、分发的过程是这样的(不管是交换机还是weblogic):
数个请求发过来,先判断一下请求的ip地址,将ip地址相同的发送到同一台server,不同的ip根据分发策略分发到不同的server.
如果一台server不可用,请求将不会发送至这一台server.原本发送至这台不可用server的请求将被发送至此server session复制目的地server.(到底是哪一台看相应的复制策略)。这样,客户端session也就不会失效,这一过程对客户是透明的。呵呵,不知道这样算不算是failover.

如果要在扯上多次请求之间涉及的长事务……还没研究,不过和用不用ejb无关,因为web都死掉了

至于判断哪个server占的内存比较高(cpu可能比较难,不过thread\队列请求数等是可以判断的),这个也可以通过自己编程jmx等来实现,甚至可以加数据挖掘来动态判断发送到哪个server,最近研究了一下f-p growth :)

当然,麻烦多多~
我不知道ejb容器实现这个是否轻而易举,不多作评论~

yuxie说话很有趣,"不过和用不用ejb无关,因为web都死掉了 "
其实集群中尽量降低Web端负担,比如HttpSession不要放太多东西,这样Web服务器之间复制工作负担就小了,Web服务器只管作为客户端和EJB传输,有EJB的服务器叫应用服务器,应用服务器管理集群复杂计算。

Web只是EJb的一种客户端,RMI/XML-RPC/Web Service/Corba都是EJB企业应用服务器的客户端。

Web只是一个简单的客户端,不是核心,这和一般人以Web为核心思维正好相反。

yuxie那句话其实说得很到位:EJB的客户端,也就是WEB,都死了,EJB的集群不集群当然已经毫无意义。 集群的“FAILOVER”,指的是服务端死掉的情况下,如何把请求导向备份服务。
事实上,所有支持EJB集群的应用服务器,在WEB,EJB“共同部署”的情况下(现实EJB生产环境至少占90%以上),EJB的集群是被缺省关闭的。

另外,“分布事务”和集群的两特性-“load balance, fail-over”是互为正交的概念。其实,“分布事务”和集群本身也互为正交,甚至和你的环境有多少机器也没有直接关系。

要理解集群,比纸上谈兵更好的方法是写个HELLO程序试验一下。

回到楼主的问题,Wang Yu的那篇文章总结了几个不错的建议,比如要SERIALIZABLE,SESSION ATTRIBUTE之间不要互相形成“引用依赖”。但是这些都是死的理论知识,最有效的办法,就是写个小程序测试一下FAIL-OVER情况下的行为。另外,在考虑“集群”概念的时候,很重要的是要弄清楚谁是客户端,谁是服务端,所谓“FAIL-OVER”是谁FAIL了之后,保证对谁的请求继续服务。

web层为什么不能负载平横还不太明白。我在琢磨琢磨

sorry,说错了。
如果连failover都不能,那这个东西也没什么用啊

web集群当然可以FAIL-OVER,之所以有SESSION REPLICATION,原因就是需要实现FAIL-OVER.
如果只是需要实现负载平衡,只需要两个互相独立的服务器和一个负载平衡器就可以。FAIL-OVER从这个意义上,可以说是集群功能的基本标志。

>之所以有SESSION REPLICATION,原因就是需要实现FAIL-OVER.
Session复制不是容错Failover吧?

failover是在机器当机的情况下,整个系统能够保证平稳运行,用户没有任何察觉。

Session复制只是为了负载平衡服务的,一个用户请求第一次可能被分发到A服务器,这是一个登陆请求,这样Session中保存其登陆信息,但是第二次请求可能被分发到B服务器,如果没有Session复制,B服务器的Session中没有其登陆信息,所以可能要求其重新登陆;当然如果该系统激活Cookie登陆,就无法Session复制了。

TSS网站就采取第二种方案,杜绝Session,使用客户端cookie,这样做的好处降低Web服务器的负载,因为Web服务器主要功能是维持客户端的TCP连接,如果它被分散去做持续纵向Session复制的话,实际利用效率会打折。

以上观点欢迎讨论。

“failover是在机器当机的情况下,整个系统能够保证平稳运行,用户没有任何察觉。”
wap集群可以做到。

“Session复制只是为了负载平衡服务的,一个用户请求第一次可能被分发到A服务器,这是一个登陆请求,这样Session中保存其登陆信息,但是第二次请求可能被分发到B服务器,如果没有Session复制,B服务器的Session中没有其登陆信息,所以可能要求其重新登陆;当然如果该系统激活Cookie登陆,就无法Session复制了。”
上边这句话错误。应用中分发器不会那么愚蠢。具体的实现请参看相应的文档。

搞了半天banq仅仅是因为分发器的原因鄙视web集群?那么当您认识到自己的错误之后,会不会收回以前的观点呢?


另外,程序中能杜绝session确实很让人羡慕,但是实际应用中,如果碰到需要身份认证的,却很难做到比session更好的实现,感觉不如尽量减少session里边的数据来的现实。

我的意思是:Session复制是可有可无,如果没有Session复制就更好,因为这会降低Web服务器接收客户端的处理能力。

failover主要是指状态的恢复,别因为一台服务器当机,把保存在内存中的状态丢失了,Session Failover只能解决保存在Session的状态的failover。

而我们有提倡尽量少用Session,所以一般不用Session来保存状态,在这个思路下,Session Failover等于一个空概念,个人认为没有实用价值。

Cache等failover概念比较重要。
另外负载平衡还有一个动态概念,EJB提供远程方法调用,所以每时每刻运行时,都有可能保持各个服务器之间负载相当,这种能力我个人认为很难靠外部技术实现的。

可以用一个比喻来解释:你作为一个外部东东,要了解我内部的运行,你肯定要派个东东深入我内部监视,但是你的东东又不要影响我运行,不成为我的负担,很难啊。单纯靠外部技术的网络信号是很难的。

所以集群在Web实现很简陋,不能实现大幅度拓展服务器能力。

Session Replication 绝对不是为负载平衡用的。绝大多数情况下,负载平衡器都有一个基本特性叫做“Session Affinity”。也就是说,同一个SESSION,即使在负载平衡的情况下,也是由同一个节点来提供服务的。这是性能优化的必然要求。
这首先要从SESSION REPLICATION的机制说起来。SESSION 复制发生的时间顺讯可能有两种:1。每次请求都复制。2。定时复制。第一种情况可以基本保障节点之间SESSION状态在绝大多数情况下是同步的,但是这样做的潜在性能代价非常高。
以上说明,从应用层面上看,“任何时间主从节点状态都同步”的要求是基本上不可能达到的。直接逻辑结论就是,主服务节点的重新导向不能在任意时间发生。这就是为什么要有SESSION AFFINITY。
AFFINITY在系统软件是一个普遍应用的优化技术。多CPU操作系统,比如WINDOWS,UNIX,LINUX,相应地有“PROCESS AFFINITY,THREAD AFFINITY”的概念,基本上出于同样的原理。CPU的L1 CACHE,在这里就对应于我们的SESSION STATE。为了不造成频繁的缓存冲洗,OS就要保证PROCESS被绑定在一个CPU上。
SESSION AFFINITY实现的方式,取决于不同的应用服务器是不同的。软件负载平衡器一般是应用服务器的一个WEB SERVER插件。这个插件里就内建了SESSION AFFINITY逻辑。硬件负载平衡器也支持SESSION AFFINITY,当然这需要一些配置。详见(http://e-docs.bea.com/wls/docs81/cluster/load_balancing.html#1044135)

综上,负载平衡在绝大多数情况下,只发生在建立SESSION之前。一旦SESSION建立,那么SESSION AFFINITY会保障同一SESSION绑定在一个节点上。而SESSION REPLICATION的目的,是在发生FAIL-OVER的情况下,会话状态不会丢失,也就是BANQ说的“用户没有感觉”。

要对每次请求都做负载平衡,有两种选择:1。你完全不计较性能,通过配置保证每个请求都做状态复制。这不是每款应用服务器都支持的。这方面没有什么JSR标准。2。你的应用完全是“应用服务器无会话状态”的。也就是说,所有的会话状态存在数据库或者客户端。这种架构并不适用于所有的应用。商业企业应用大多数都有相当数量的会话状态和CONTEXT状态,采用数据库状态会带来频繁的数据库操作,而客户端状态首先未必能够容纳那么多数据,即使能够容纳,每次请求都要附带大量状态数据,会对网络传输造成压力。

> REPLICATION,原因就是需要实现FAIL-OVER.
> Session复制不是容错Failover吧?
>
> failover是在机器当机的情况下,整个系统能够保证平稳运行
> 没挥腥魏尾炀酢?
>
> Session复制只是为了负载平衡服务的,一个用户请求第一次?
> 能被分发到A服务器,这是一个登陆请求,这样Session中保存
> 涞锹叫畔堑诙吻肭罂赡鼙环址⒌B服务器,如果没有
> ession复制,B服务器的Session中没有其登陆信息,所以可能
> 笃渲匦碌锹剑坏比蝗绻孟低臣せCookie登陆,就无法Ses
> ion复制了。
>
> TSS网站就采取第二种方案,杜绝Session,使用客户端cookie
> 庋龅暮么档Web服务器的负载,因为Web服务器主要功?
> 是维持客户端的TCP连接,如果它被分散去做持续纵向Session
> 粗频幕埃导世眯驶岽蛘邸?
>
> 以上观点欢迎讨论。
>

1。所谓状态恢复,就是通过状态复制实现的。状态复制不一定要在两个节点之间。比如WEBSPHERE,就是把状态复制到数据库。在WEBSPHERE里,状态复制有两种方式,通过内存复制(类似WEBLOGIC),或者通过数据库永久化。无论那种方式,对于应用而言都是透明的,目的都是在FAIL-OVER情况下实现透明的状态恢复。

2。EJB的负载平衡,也不是所谓“时时刻刻都在发生”。EJB的负载平衡,同样有“SESSION AFFINITY”的优化,当然这是针对于SFSB。对于SLSB而言,既然没有状态,和WEB负载平衡就不具备可比性。
EJB的负载平衡,不但在概念上,甚至在算法上,实现上,都和WEB集群完全一致。

并且,EJB的负载平衡和 WEB负载平衡相比,作用要小得多。这样说的原因:

第一:绝大多数生产环境里,EJB的客户端是WEB,并且EJB和WEB是共同部署。也就是说,如果EJB容器死了,那么WEB容器肯定也死了。EJB的负载平衡逻辑是建入在STUB里的。既然WEB已经死了,那么STUB也就不存在了。谈何EJB负载平衡?

第二,LOCAL EJB是没有集群功能的。

第三,ENTITY EJB是没有集群功能的。

第四,在WEB,EJB共同部署的情况下,即使WEB访问EJB是通过REMOTE INTERFACE, 应用服务器也会做优化,把访问当作类似LOCAL INTERFACE的方式处理(目的是为了省略不必要的对象序列化)。这样获得的STUB有目的地关闭了集群逻辑。原因在一中已经描述。

所以,EJB的集群,只在下面的情况下才会发生:
REMOTE SESSION BEAN(STATEFUL或者STATELESS), 并且客户端不部署在同一JVM里。即使在这样的情况下,EJB开发者还要保证EJB方法是IDEMPOTENT的。

不明白BANQ为什么对EJB集群情有独衷。更不动所谓WEB集群“简陋”是什么意思。二者的实现,在代码层面都是用同样的代码,何来一者简陋另一者高级?

> 我的意思是:Session复制是可有可无,如果没有Session复制
> 透茫蛭饣峤档Web服务器接收客户端的处理能力。
>
> failover主要是指状态的恢复,别因为一台服务器当机,把保
> 嬖谀诖嬷械淖刺Я耍Session
> Failover只能解决保存在Session的状态的failover。
>
> 而我们有提倡尽量少用Session,所以一般不用Session来保存
> 刺谡飧鏊悸废拢Session
> Failover等于一个空概念,个人认为没有实用价值。
>
> Cache等failover概念比较重要。
> 另外负载平衡还有一个动态概念,EJB提供远程方法调用,所?
> 每时每刻运行时,都有可能保持各个服务器之间负载相当,这
> 帜芰ξ腋鋈巳衔苣芽客獠考际跏迪值摹?
>
> 可以用一个比喻来解释:你作为一个外部东东,要了解我内部
> 脑诵校憧隙ㄒ筛龆钊胛夷诓考嗍樱悄愕亩植
> 要影响我运行,不成为我的负担,很难啊。单纯靠外部技术的
> 缧藕攀呛苣训摹?
>
> 所以集群在Web实现很简陋,不能实现大幅度拓展服务器能力?

很多人还是不理解EJB动态负载平衡的优势,前面我已经举例了,Web负载平衡是对请求信号分发,但是每次请求对CPU的负载肯定是不一样的,主要取决于这个请求调用的那个组件方法(EJB方法)的运行量,根据业务逻辑不同,不同EJB方法运行占据CPU就不一样。

所以,”Web负载平衡是对请求信号分发“方式很难将每个服务器负载都平衡成50%,因为EJB方法运行量不一样,有的服务器对一个请求可能处理耗费80%CPU,但是运气不好的话,下一个需要大负载的请求又可能发给它处理,累死它。

而EJB的远程方法和JNDI则可以平衡这种处理,当这台服务器负载已经达到80%,又有请求发给它,它会通过JNDI和远程调用,将这个请求调用的EJB方法转发调用其他负载较低的服务器上的EJB。

我想我说的够明白了。这就是EJB集群的智能,这也是EJB诞生的首要原因,因分布式计算而生。

接着谈failover,上述服务器转发调用其他服务器时,就需要通过JNDI查询了(因为这是EJB调用的首要步骤),这时failover就会被激活,因为总不能找一个当机的服务器给它用吧.

负载平衡以及失效转发行激活有三种方式:



另外负载平衡以及失效转发行激活是时刻都可能发生,但是因为这样耗费性能,所以,你可以事先设定不要让其频繁发生。

EJB的集群如此复杂,因此EJB在当初设计时,很难在性能和OO设计之间取得一个平衡,所以EJB2.1之前都是倾向性能,忽视OO设计,而后者成为Spring等开源软件的攻击目标,当然EJB3又一次取得了平衡。

如果Web集群和EJB集群差不多,何必走这么多弯路,何必发明EJB呢,这个基本常识我想初学者也会明白的。