我是不是还需要在 CDI bean 上使用 EJB @Clustered 来进行分布式应用程序
Posted
技术标签:
【中文标题】我是不是还需要在 CDI bean 上使用 EJB @Clustered 来进行分布式应用程序【英文标题】:Do I need to also use EJB @Clustered on CDI beans for distributed application我是否还需要在 CDI bean 上使用 EJB @Clustered 来进行分布式应用程序 【发布时间】:2016-05-08 23:14:46 【问题描述】:我有一个在 Wildfly 9 应用服务器上运行的带有 EJB 3.1 和 CDI bean 的 Web 应用程序。我已经阅读了有关安装和部署 HA 独立集群环境的 Jboss 文档,并且根据 JBoss 文档,所有 EJB 必须使用 @Cluster 注释进行注释,以便在不同的集群节点之间分发。我的问题是,我是否需要像使用 EJB 一样注释我的 CDI bean?或者我只需要在我的 web.xml 上定义 <Distributable />
标签,容器就会将所有 CDI bean 作为分布式对象处理?
【问题讨论】:
这可能取决于 bean 的范围,但我的第一个猜测是否定的。请参阅 EJB 将需要集群,因为它们是池化的并且可能保存有状态的信息。另一方面,CDI bean 很大程度上不是池化的——而是按需创建的。除非您正在处理 SessionScoped CDI bean,在这种情况下,它们跨集群的复制会对应用程序产生影响,不是因为它们是 CDI bean,而是因为它们是集群的 【参考方案1】:从 bean 的角度来看,集群是一个关注状态的问题。想一想:如果一个 bean 不保持状态,那么跨集群复制它的目的是什么?
这让我们现在想到了一个问题,即您将从跨集群复制的 CDI bean 中获得什么。
@RequestScoped
CDI bean 不需要跨越集群中的节点:它是按需创建的,不会超出单个 HTTP 请求。没有太多的案例可以在集群中复制它
@SessionScoped
CDI bean 将从复制中受益,因为它包含宝贵的货物:会话信息。当集群中的一个节点死亡时,应用程序将受益于能够将该 bean 迁移到另一个节点。但是这个范围与 HTTP 会话相关联,该会话完全由一个单独的机制复制,并且应该独立于 @Clusterable
注释来负责复制 bean 中的数据。请记住,EJB,甚至 @Stateful
都没有连接到 HTTP 会话
@ViewScoped
bean 也与 HTTP 会话相关联,因此 @SessionScoped
bean 的优点也适用于此。
这里的总结是,在集群中负责复制会话的任何机制都应该足以满足需要复制的 CDI bean。 @Clusterable
不适用于此处
编辑: 再深入一点the CDI spec,它支持了我的假设:您的 CDI bean 需要做的就是能够支持普通会话激活和钝化,即可序列化,你应该没事:
6.6.1。钝化能力豆
如果容器能够将任何空闲实例的状态临时传输到辅助存储,则称为具有钝化能力的 bean。
根据 EJB 规范的定义,有状态会话 bean 在以下情况下具有钝化能力:
bean 的拦截器和装饰器具有钝化能力,并且,
有状态会话 bean 没有将 passivationCapable 标志设置为 false。
根据 EJB 规范的定义,无状态会话 bean 或单例会话 bean 不具备钝化能力。
当且仅当 bean 类是可序列化的并且 bean 的所有拦截器和装饰器都具有钝化能力时,托管 bean 才具有钝化能力。
生产者方法具有钝化能力当且仅当它从不返回在运行时不具有钝化能力的值。
生产者字段具有钝化能力当且仅当它从不引用在运行时不具有钝化能力的值。
【讨论】:
谢谢@Kolossus,我的问题是关于有状态会话bean,目前集群环境还没有准备好,但让我们试试你提出的解决方案。 我认为 CDI 和 EJB 的 API 规范中没有 'code'@Clusterable 注释,我只能找到 EJB 类的 Jboss 'code'@Clustered 注释。我在 JBoss 论坛上读过一篇文章,其中提到不需要集群 CDI bean !一旦我在应用服务器上尝试一下,我会以任何方式更新你。 我认为根据我在部署 EJB 时收到的 Wildfly 日志文件,不推荐使用 @Clustered 注释。除了 Singleton 之外,我的 EJB 一切都顺利进行,它必须使用供应商特定的 API 开发。@ApplicationScoped
怎么样? CDI bean 持有的状态是否在集群节点之间复制?
Nope @leopal:` @ApplicationScoped
不是具有钝化功能的范围。 Only the Session and Conversation scopes are passivation-capable以上是关于我是不是还需要在 CDI bean 上使用 EJB @Clustered 来进行分布式应用程序的主要内容,如果未能解决你的问题,请参考以下文章