【问题标题】:What's the best way to share business object instances between Java web apps using JBoss and Spring?使用 JBoss 和 Spring 在 Java Web 应用程序之间共享业务对象实例的最佳方式是什么?
【发布时间】:2008-11-06 09:54:26
【问题描述】:

我们目前有一个 Web 应用程序加载一个 Spring 应用程序上下文,该上下文实例化了一堆业务对象、DAO 对象和 Hibernate。我们希望与另一个 Web 应用程序共享此堆栈,以避免有多个相同对象的实例。

我们研究了几种方法;使用 JMX 或 JNDI 或使用 EJB3 公开对象。

不同的方法都有各自的问题,我们正在寻找一种轻量级的方法。

关于如何解决这个问题的任何建议?

编辑:我收到了 cmets 要求我详细说明一下,所以这里是:

我们要解决的主要问题是我们只想拥有一个 Hibernate 实例。这是由于在运行多个使用同一数据源的客户端应用程序时,Hibernate 的二级缓存失效的问题。此外,业务/DAO/Hibernate 堆栈越来越大,因此不复制它更有意义。

首先,我们尝试研究如何将业务层单独暴露给其他 Web 应用程序,Spring 以少量 XML 的价格提供了 JMX 包装。但是,我们无法将 JMX 实体绑定到 JNDI 树,因此我们无法从 Web 应用程序中查找对象。

然后我们尝试将业务层直接绑定到 JNDI。尽管 Spring 没有为此提供任何方法,但使用 JNDITemplate 绑定它们也很简单。但这导致了几个新问题: 1) 安全管理器拒绝访问 RMI 类加载器,因此一旦我们尝试调用 JNDI 资源上的方法,客户端就会失败。 2) 一旦安全问题得到解决,JBoss 抛出 IllegalArgumentException: object is not an instance of declaring class。稍微阅读一下,我们发现我们需要 JNDI 资源的存根实现,但这似乎很麻烦(也许 Spring 可以帮助我们?)

我们还没有过多地研究 EJB,但是在前两次尝试之后,我想知道我们想要实现的目标是否完全可行。

总结一下我们想要实现的目标:一个 JBoss 实例,多个 Web 应用程序利用 DAO 层和 Hibernate 之上的一组业务对象。

最好的问候,

尼尔斯

【问题讨论】:

  • 您能评论一下 1. 您要解决什么问题; 2.您在提到的各个方法中发现的问题。这将允许一个更集中的答案......
  • 很难用 300 个字符全部说完,所以我编辑了问题以添加更多细节 :-)

标签: java hibernate spring jboss ejb-3.0


【解决方案1】:

Web 应用程序是否部署在同一台服务器上?

我不能代表 Spring,但使用 Session Bean 将业务逻辑移入 EJB 层很简单。

应用程序组织是直截了当的。逻辑进入会话 Bean,这些会话 Bean 捆绑在单个 jar 中,作为带有 ejb-jar.xml 文件的 Java EE 工件(在 EJB3 中,这可能实际上是空的)。

然后将您的实体类捆绑到一个单独的 jar 文件中。

接下来,您将在各自的 WAR 文件中构建每个 Web 应用程序。

最后,所有的 jars 和 war 都被捆绑到一个 Java EE EAR 中,并带有关联的 application.xml 文件(同样,这可能是非常小的,只需枚举 EAR 中的 jars)。

此 EAR 被批量部署到应用服务器。

每个 WAR 实际上都是独立的——它们自己的会话、上下文路径等。但它们共享公共 EJB 后端,因此您只有一个二级缓存。

您还可以使用本地引用和调用语义来与 EJB 对话,因为它们位于同一服务器中。这里不需要远程调用。

我认为这很好地解决了您遇到的问题,并且在带有 EJB 3 的 Java EE 5 中非常简单。

此外,据我了解,您仍然可以在大部分工作中使用 Spring,但我不是 Spring 人,因此无法详细说明。

【讨论】:

  • 是的,一切都部署到同一台服务器上。这看起来很有趣,我今天将给 EJB 一个机会。我对 Spring 的看法是它提供了包装 bean 的功能,例如JMX 没有任何代码,但显然不适用于 EJB。不管怎样,我今天看看 EJB 方法。
【解决方案2】:

【讨论】:

    【解决方案3】:

    Terracotta 可能很适合这里(披露:我是 Terracotta 的开发人员)。 Terracotta 在 JVM 级别透明地集群 Java 对象,并与 Spring 和 Hibernate 集成。它是免费和开源的。

    正如您所说,多个客户端 Web 应用程序使用 L2 缓存的问题是使这些缓存保持同步。使用 Terracotta,您可以集群单个 Hibernate L2 缓存。每个客户端节点都使用它的集群缓存副本,并且 Terracotta 保持同步。 This link 解释更多。

    对于您的业务对象,您可以使用 Terracotta 的 Spring integration 来集群您的 bean - 每个 Web 应用程序都可以共享集群 bean 实例,并且 Terracotta 透明地保持集群状态同步。

    【讨论】:

      【解决方案4】:

      实际上,如果您想要一个轻量级解决方案并且不需要事务或集群,只需使用 Spring 对 RMI 的支持。它允许使用最新版本中的简单注释远程公开 Spring bean。见http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html

      【讨论】:

      • 我已经使用这种方法从 webapp 访问共享的 Spring bean。虽然我仍然觉得可能有更好/更清洁的解决方案,但它仍然有效。
      • 如果您不喜欢 RMI,Spring 提供了其他一些远程处理选项 - Hessian、Burlap 和 HttpInvoker(Spring 的自定义远程处理解决方案 - 基于 HTTP 的 Java 序列化)。当然也总是有网络服务。
      【解决方案5】:

      您应该查看 Terracotta 参考 Web 应用程序 - 考官。它具有您正在寻找的大部分组件 - 它具有 Hibernate、JPA 和带有 MySQL 后端的 Spring。

      已预先调整为最多可扩展到 16 个节点和 20k 个并发用户。

      在这里查看:http://reference.terracotta.org/examinator

      【讨论】:

        【解决方案6】:

        感谢您到目前为止的回答。我们还没有完全做到这一点,但我们现在已经尝试了一些事情,并且更清楚地看到了事情。这是一个简短的更新:

        似乎最可行的解决方案是 EJB。但是,这将需要对我们的代码进行一些更改,因此我们现在不会完全实现该解决方案。我几乎很惊讶我们在这里找不到一些 Spring 功能来帮助我们。

        我们还尝试了 JNDI 路由,它以所有共享接口都需要存根结束。考虑到一切都在同一台服务器上,这感觉很麻烦。

        昨天,我们在 JMX 方面取得了小小的突破。尽管 JMX 绝对不适合这种用途,但我们已经证明它可以做到——无需更改代码和最少的 XML(非常感谢 Spring 提供的 MBeanExporter 和 MBeanProxyFactoryBean)。这种方法的主要缺点是性能和我们的域类必须通过 JBoss 的 server/lib 文件夹共享的事实。即,我们必须从 WAR 中删除一些依赖项并将它们移动到 server/lib,否则当业务层从我们自己的域模型返回对象时,我们会得到 ClassCastException。我完全理解为什么会发生这种情况,但这对于我们想要实现的目标并不理想。

        我认为是时候进行一些更新了,因为看起来最好的解决方案需要一些时间来实施。完成这项工作后,我会在这里发布我们的发现。

        【讨论】:

        • 我和其他人在这个帖子上多次建议过,但是你看过 Terracotta 吗?与迄今为止提出的所有其他解决方案不同,它是专门为您所要求的状态共享而设计的。
        【解决方案7】:

        Spring 确实有一个您可能感兴趣的集成点:EJB 3 injection nterceptor。这使您能够从 EJB 访问 spring bean。

        【讨论】:

          【解决方案8】:

          我不太确定您要解决什么问题;在一天结束时,每个 jvm 要么具有对象的复制实例,要么具有代表存在于另一个(逻辑)服务器上的对象的存根。

          您可以设置第三个“业务逻辑”服务器,该服务器具有一个远程 API,您的两个 Web 应用程序可以调用该 API。典型的解决方案是使用 EJB,但我认为 Spring 在其堆栈中内置了远程处理选项。

          另一种选择是使用某种形式的共享缓存架构...它将在服务器之间同步对象更改,但您仍然有两组实例。

          【讨论】:

            【解决方案9】:

            看看JBossCache。它允许您在多个 JVM 实例(相同或不同)之间轻松共享/复制数据映射。它易于使用,并且有很多线级协议选项(TCP、UDP 多播等)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-01-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多