2012-02-25 80 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

相關問題