无状态 EJB 和集群

Stateless EJB and clustering

场景: EjbA 和 EjbB 都是远程无状态会话 bean。

@Stateless
public class EjbA
{
  @EJB
  private EjbB b;

  public void foo(){
    b.method1();
    b.method1();
    b.method2();
  }
}

这些方法中的任何一个调用 b 是否正确 可以在集群环境中的不同 node/VM 上发生吗?

甚至调用 method1?

我的意思是,如果某些客户端调用方法 foo,是否会发生 在此交易中 method1 在 node1 上被调用 和下一次调用 method1,在 foo() 的同一次调用期间, 转到 node2 上的 Ejb 实例?

解读 "Enterprise JavaBeans 3.1" 中的以下引述:

"...对 SLSB 代理的每次调用都独立于 之前和之后的那些。事实上,它的底层 bean 实例 可以在请求之间互换。"

我会说是的。

有什么方法可以确保这些调用发生在同一个 node/VM 上的同一个无状态会话 bean 实例上?

如果我的第一个假设是正确的,那应该是不可能的。

例如使用单例只能确保每个 VM 的 Ejb 是唯一的。 所以在集群环境中它不会给我这个保证。

Is it correct that any of these method calls on b can happen on a different node/VM in a clustered environment?

是的,方法调用可以是远程的 - 只要您在 EjbB

上有 properly setup the remote interface

Even the calls to method1?

I mean if some client calls method foo, can it happen that in the this transaction method1 is called on node1 and the next call to method1, during the same invocation of foo(), goes to an Ejb instance on node2?

Interpreting the following quote from "Enterprise JavaBeans 3.1":

"... each invocation upon a SLSB proxy operates independently from those both before and after. In fact, its underlying bean instances may be swapped interchangeably between requests."

I would say yes.

我 100% 同意您的评价。事实上,容器实现者可以在每次方法调用时自由地创建和销毁无状态会话 Bean——它们彼此独立。

Is there any way to ensure that these calls happen to the same stateless session bean instance

您必须使 EJB 成为 @Singleton. That way you ensure that it's only created once per EJB Container Classloader

on the same node/VM?

是的,您可以确保所有调用都是本地的——不要定义远程接口。 By default all EJBs only expose local interfaces;这意味着如果您不做任何额外的工作 - 您总是在调用本地 EJB。

没有可靠的方法 "force" 独立的方法调用由同一个无状态 Bean 处理。如果您试图在 EjbA 和 EjbB 之间维护 "conversational state",那么这就是 Stateful Session bean 的用途。使用有状态会话 Bean,方法调用不仅保证由同一个 bean 处理,而且 EjbB 将能够记住来自 EjbA 的方法调用之间的状态。在此设置中,EjbB 将完全专用于 EjbA 的特定实例,并且不会为任何其他客户端提供服务,直到 EjbA 结束会话(例如,通过被销毁)。