一般来说,一个相对大型的J2EE系统,都会采用以下这种Cluster的架构,
 
 Load Balancer -Web Server 1,2 -App Server 1,2
 
而其中Web Server 1,Web Server 2交叉连接App Server1,App Server 2叫做Active/Active Mode;Web Server 1直连App Server1,Web Server 2直连App Serer2,叫做Active/Standby Mode。
 
Cluster的好处这里就不提了,这里想谈谈Cluster的Limitation。
 
1. Failover并不能完全避免错误。我们期望的是,一个Request过来,假如接受请求的App Server Down了,请求能够无缝的连接到另一台App Server去,没错,理论上应当如此。但是请注意Failover本身有其前提条件,“在方法调用之间”。而大多数的情况是,Client端会直接收到错误信息,除非这个方法是“幂等”的,例如Listing,Display,只有在这种情况下,某些足够聪明的Load Balancer才会将Failover转移到另一个Instance上面。
 
2. 你可能会认为在一个Transaction中的所有方法都应该是幂等的,因为当请求失败时,Transaction会Rollback,对系统状态所做的改变全部会撤销,但实际的情况是,Transaction的界限很可能无法包含所有的RMI Call的边界。
 
3. 在Cluster的环境中,HTTP Session的使用有很多的限制,最重要的一点是Session中的Object必须是Serializable的。但是一些Design Pattern或者MVC Framework会在HTTP Session中存储一些UnSerializable的Object,如Servlet上下文,Web Service的引用等等,这种设计在Cluster下是无法正常工作的。因此,并不是所有的Standalone Application能够透明的迁移到Cluster中来的。
 
4. 静态变量的使用要非常小心。传统的Design Pattern “Singleton”会使用静态变量来实现对多个Object之间的状态共享,这个在Cluster中是完全失效的,因为Cluster中的每个Server Instance都会有自己的一个JVM,这样打破了这个Design Pattern的机制。当然,一定要使用这个模式生效,可以考虑用DB来保存状态。
 
5. 交叉Mode比直连Mode更灵活?非也。大多数的的Server都是Web Container和EJB Container在同一个JVM Instance中运行的,让EJB Container处理来自其他Server的Web Container的Request不见得比处理自己Web Container的Request来得高效。如果EJB Container所在的Server Down了,Web Container也基本上Down了,交叉Mode没有提高可用性。交叉Mode有可能会导致Performance的低下,因为容易产生不必要的,跨Server的交互,如果方法中有Transaction,那么Transaction的边界就要包含多个Server Instance。
 
6. 实际上,很多厂商包括JES,Weblogic,JBoss等等,对于EJB的Load Balancer都做了优化,优先选择在同一个Server Instance上的EJB。这就成了Active/Standby,也就是直连Mode了。