2015-01-14 25 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子系统的有效缓存。如果没有定义特定的缓存,则假定缓存容器的默认缓存。此缓存用作注册表,其中的节点可以提供给定的服务,并且通常使用**复制缓存**配置。 –