Singleton与群集中的有状态远程EJB引用

时间:2011-03-28 14:24:49

标签: java jboss singleton cluster-computing stateful-session-bean

我正在使用带有几个项目的vanilla JBossAS 6服务器来测试集群JBoss环境的功能。我遇到的问题是,如果我将EJB引用从一个节点中的EJB(另一种类型)转移到另一个节点中相同类型的实例,则在方法调用时抛出异常,说明指定bean的long_alphanumeric_key 键未在缓存中注册(InfinispanStatefulCache)。

问题在于,当我需要传输的对象上使用Singleton注释而不是Stateful注释时,传输的对象可以完美地工作,成功地在创建它的服务器上调用共享EJB的方法。问题是这个案例与HA-Singleton有相同的缺陷。以前通过在HA-JNDI树上查找获得的所有传输引用。

对我正在努力实现的目标有所了解:

我目前需要的是在节点之间共享一个有状态EJB的实例,比如HA-Singleton。不使用HA-Singleton的原因是这种类型的单例的状态仅在集群的主节点上保留,因此如果节点关闭或失败,则实例的状态将丢失。

使用有状态bean可以让我保留集群上的状态,从而防止在节点发生故障时丢失状态。我还没有完全理解JBoss和Infinispan缓存是如何工作的,但据我所知, @Clustered 带注释的有状态bean状态会自动在集群上复制。

我们已经注意到在当前JBoss版本中使用Singletons和HA-Singletons的问题,因此欢迎任何类型的文档或模式来帮助解决此设计更改。

另外,我将非常感谢能够让我了解Infinispan缓存和JBoss群集如何工作的任何文档。到目前为止,我一直在阅读的材料与使用JBossCache而不是Infinispan的旧JBoss版本混合使用。

谢谢前进,
德国

1 个答案:

答案 0 :(得分:2)

不幸的是,JBoss AS6或AS7还不支持集群EJB单例 - 我认为这正是你所寻求的。 HA-Singleton将确保仅在群集的单个节点上启动某个服务的一个实例。这似乎不适合您的用例。看起来你真的只需要分发EJB单例的状态。 这是我推荐的,使用本地EJB单例,但使用infinispan来存储其分布式状态: *对于初学者,我建议您使用AS7而不是AS6,因为Infinispan集成更加成熟。 *在AS7中,您可以直接在Singleton中使用infinispan缓存。 e.g。

@Singleton
public class MySingleton {
  // This references the same infinispan cache container used for sfsb replication
  @Resource(lookup="java:jboss/infinispan/container/ejb")
  private CacheContainer container;
  private Cache<?, ?> cache;

  @PostContruct
  public void init() {
    // This will create a cache for use by this singleton
    // Any state to be distributed should be stored in the cache.
    this.cache = container.getCache(this.getClass().getName());
  }

  @PreDestroy
  public void destroy() {
    this.cache.stop();
  }
}