2015-01-14 21 views
1

我正試圖在Wildfly 8.2上創建一個簡單的集羣Singleton。我配置了2個Wildfly實例,運行在獨立的集羣配置中。我的應用程序已部署到兩者,並且我可以毫無問題地訪問它。Clustered Singleton使用Wildfly?

我的集羣EJB是這樣的:

@Named 
@Clustered 
@Singleton 
public class PeekPokeEJB implements PeekPoke { 

    /** 
    * Logger for this class 
    */ 
    private static final Logger logger = Logger 
      .getLogger(PeekPokeEJB.class); 

    private static final long serialVersionUID = 2332663907180293111L; 

    private int value = -1; 

    @Override 
    public void poke() { 
     if (logger.isDebugEnabled()) { 
      logger.debug("poke() - start"); //$NON-NLS-1$ 
     } 

     Random rand = new SecureRandom(); 
     int newValue = rand.nextInt(); 
     if (logger.isDebugEnabled()) { 
      logger.debug("poke() - int newValue=" + newValue); //$NON-NLS-1$ 
     } 

     this.value = newValue; 

     if (logger.isDebugEnabled()) { 
      logger.debug("poke() - end"); //$NON-NLS-1$ 
     } 
    } 

    @Override 
    public void peek() { 
     if (logger.isDebugEnabled()) { 
      logger.debug("peek() - start"); //$NON-NLS-1$ 
     } 

     if (logger.isDebugEnabled()) { 
      logger.debug("peek() - value=" + value); //$NON-NLS-1$ 
     } 

     if (logger.isDebugEnabled()) { 
      logger.debug("peek() - end"); //$NON-NLS-1$ 
     } 
    } 
} 

...我已經寫了一個非常簡單的RESTful服務,讓我打電話給通過瀏覽器這些方法...

@Path("/test") 
@Named 
public class TestRS extends AbstractRestService { 
    /** 
    * Logger for this class 
    */ 
    private static final Logger logger = Logger.getLogger(TestRS.class); 

    @Inject 
    private PeekPoke ejb = null; 

    @GET 
    @Path("/poke") 
    public void poke() { 
     if (logger.isDebugEnabled()) { 
      logger.debug("poke() - start"); //$NON-NLS-1$ 
     } 

     this.ejb.poke(); 

     if (logger.isDebugEnabled()) { 
      logger.debug("poke() - end"); //$NON-NLS-1$ 
     } 
    } 

    @GET 
    @Path("/peek") 
    public void peek() { 
     if (logger.isDebugEnabled()) { 
      logger.debug("peek() - start"); //$NON-NLS-1$ 
     } 

     this.ejb.peek(); 

     if (logger.isDebugEnabled()) { 
      logger.debug("peek() - end"); //$NON-NLS-1$ 
     } 
    } 
} 

我可以從單個Wildfly實例調用peekpoke方法,並獲得期望值。但是,如果我試圖從一個實例中調用poke,並且從另一個實例中調用poke,我會發現這些值不會跨EJB複製。

我的印象是,一個集羣單例將在兩個應用程序服務器之間複製'value'的值,無論我從哪個主機調用peek來提供相同的值。這是不正確的?有什麼我遺漏,仍然需要添加到此代碼?

我會很感激任何幫助,你可以給我!謝謝!

回答

6

辛格爾頓會話bean提供一個正式的編程結構,保證會話bean將再次每個應用在特定Java虛擬機(JVM)被實例化。

JSR 318:企業JavaBeans TM,3.1版說:

一個單會話bean是一個會話Bean組件是 每個應用程序實例化一次。在容器是 分佈在多個虛擬機的情況下,每個應用程序將具有單件的一個 bean實例爲每個JVM

因此,在一個集羣應用,每個集羣成員將具有其自己的單實例會話bean和數據不在JVM實例之間共享(在Wildfly實現中)。

在Wildfly中,如果您只需要一個羣集範圍內的單例實例,則可以使用SingletonService實現。使用SingletonService,目標服務安裝在羣集中的每個節點上,但只在任何給定時間在一個節點上啓動。

參見:

UPDATE:

WildFly 10增加部署一個給定的應用程序作爲 「單身部署」的能力。這是在AS 6.0及更早版本中存在 的新功能的實現。當部署到一組羣集的 服務器時,單一部署將只在任何給定時間在單個節點上部署在 。如果部署處於活動狀態的節點停止或 失敗,則部署將自動在另一個節點上啓動。

參見:WildFly 10 Final is now available!

+1

費德里科嗨,你和文件爲說10 wildfly,「如果在其上部署主動停止或失敗的節點,部署將自動另一個節點上啓動」我想知道,當一個節點停止或失敗並且另一個節點啓動時,新節點是否將數據保存在舊節點中? – xxlali

+1

@xxlali根據文檔:單例策略的'cache-container'和cache屬性必須引用來自Infinispan子系統的有效緩存。如果沒有定義特定的緩存,則假定緩存容器的默認緩存。此緩存用作註冊表,其中的節點可以提供給定的服務,並且通常使用**複製緩存**配置。 –