关于java:使用Wildfly的集群Singleton吗?

Clustered Singleton using Wildfly?

我正在尝试在Wildfly 8.2上创建一个简单的集群Singleton。我已经配置了2个Wildfly实例,它们在独立的群集配置中运行。我的应用程序已部署到这两个应用程序,并且我可以毫无问题地访问它。

我的集群EJB看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@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服务,让我可以通过浏览器调用这些方法...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@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,然后从另一实例调用peek,我会看到这些值没有跨EJB复制。

给我的印象是,群集单例将在两个应用程序服务器之间复制'value'的值,无论我从哪个主机进行peek调用,都提供相同的值。这不正确吗?我缺少一些仍需要添加到此代码中的东西吗?

感谢您能给我任何帮助!谢谢!


Singleton会话Bean提供了一种正式的编程结构,该结构可确保在特定Java虚拟机(JVM)中每个应用程序实例化一个会话Bean。

JSR 318:Enterprise JavaBeans TM版本3.1说:

A Singleton session bean is a session bean component that is
instantiated once per application. In cases where the container is
distributed over many virtual machines, each application will have one
bean instance of the Singleton for each JVM

因此,在集群应用程序中,每个集群成员将拥有自己的单例会话bean实例,并且不会在JVM实例之间共享数据(在Wildfly实现中)。

在Wildfly中,如果在集群范围内只需要一个单例实例,则可以使用SingletonService实现。使用SingletonService,目标服务将安装在群集中的每个节点上,但在任何给定时间仅在一个节点上启动。

请参阅:

  • 实施HA Singleton
  • cluster-ha-singleton:在JAR中部署的SingletonService已启动
    由SingletonStartup并由EJB访问

更新:

WildFly 10 adds the ability to deploy a given application as a
"singleton deployment". This is a new implementation of a feature that
existed in AS 6.0 and earlier. When deployed to a group of clustered
servers, a singleton deployment will only deploy on a single node at
any given time. If the node on which the deployment is active stops or
fails, the deployment will automatically start on another node.

请参阅:WildFly 10 Final现在可用!