2012-02-25 84 views
3

我有一个运行在GlassFish上的Java EE 6 Web应用程序。该应用程序使用2个本地Singleton EJB MySingleton实例。 MySingleton的每个实例都通过API连接到第三方软件。GlassFish在不同物理服务器上运行EJB

MySingleton.java

@Singleton 
@LocalBean 
public class MySingleton { 
    @PersistenceContext private EntityManager em;  
    private ThirdPartyAPI thirdPartyAPI; 
    ... 
} 

MySingletonManager.java

@Singleton 
@LocalBean 
public class MySingletonManager { 
    @EJB private MySingleton mySingletonA; 
    @EJB private MySingleton mySingletonB;  ///Aargh! They can't run on the same server!! 
    ... 
} 

这里有约束:

  1. 第三方软件供应商要求其软件运行的每个插件在不同的物理服务器上使用ThirdPartyAPI
  2. MySingleton使用注入的实例EntityManager,在同一PersistenceContext上查询和事务所需的实例。

为了满足约束条件1,我认为我需要远程访问辛格尔顿EJB:我需要告诉应用服务器像“在服务器A上运行mySingletonA,mySingletonB服务器B”。为此,我看到有可能通过JNDI来调用远程EJB。

为了满足约束2,我认为我需要使用GlassFish clustering,因为PersitenceContext需要在MySingleton的两个实例间共享。

不幸的是,我无法找到任何有关如何将2个tecnhologies结合使用的参考(远程EJB和集群)。

我正在寻找有关此方案的首选体系结构的提示或建议,并最终提供了一些实施准则。

回答

2

夫妇的事情...

首先,如果你连接到外部EIS系统,“正确”的方式是写一个JCA适配器和使用@Resource注入一个实例。他们写起来相当简单,亚当比恩写了一个简单的例子。想象一下@Resource就像为你的应用程序创建一个自定义数据源一样。一旦你全力以赴,它确实非常有趣。编写任何使用套接字或同步的EJB在技术上不受JEE6规范的支持。

如果你这样做,那么你可以在你的集群的两个成员上安装这个适配器。每个集群成员都可以指向第三方软件的外部实例。如果任何一个集群成员关闭,一切都会继续运行,只是桃色。

但是......如果你真的想要做的事情与单身的EJB硬盘的方式,你也许可以做到这一点,而不是:

首先,摆脱MySingletonManager的。集群是透明的,你不应该知道你是集群的。第二个改变你的单身代码:

@Singleton 
@Remote 
public class MySingleton { 
    @PersistenceContext private EntityManager em;  
    private ThirdPartyAPI thirdPartyAPI; 
    ... 

} 

明白,一个Singleton CAN NOT有状态是很重要的。如果ThirdPartyAPI在调用之间保持状态,就会发生有趣的事情。您还必须在thirdPartyAPI周围放置循环连接代码装饰器,以便连接到两个ThirdPartyServers。最后,创建一个GlassFish群集并在群集中部署您的EJB。注入到你这样的代码:

@EJB MySingleton myIns; 

这将自动将您的群集中的地方找到一个EJB的,给你一个句柄。现在,假设这一切都有效,并且我没有遗漏任何东西,那么您现在有一个并发问题,因为默认情况下,访问任何EJB都是序列化的。您可以添加@ConcurrencyAttribute(NO_LOCK),但EntityManager不是线程安全的,它也是事务性的。总的来说,Singleton EJB会给你带来很多问题。花时间写一个JCA适配器!

+0

感谢您的回答。鉴于这个话题的复杂性,我需要一些时间......顺便说一下:你能否澄清(最终有一些参考文献)“单身人士不能拥有一个国家”? – perissf 2012-02-28 14:02:50

+0

刚刚发现这篇关于Singletons的有趣文章http://java.sun.com/developer/technicalArticles/Programming/singletons/。感谢提示 – perissf 2012-02-28 14:23:09

+0

集群J2EE环境中的单例实际上在集群中的每个节点上都有一个单例实例。否则,就会出现单点故障......因此,在群集环境中,将状态置于单例时必须采取额外的预防措施,因为它们不是“真正的”Singleton。管理这个最简单的方法是避免将状态放入群集单例中。 – 2012-02-28 15:57:54

相关问题