【问题标题】:EJB3 - Session Bean calling method of another bean interfaceEJB3 - 另一个 bean 接口的会话 Bean 调用方法
【发布时间】:2009-07-26 11:33:52
【问题描述】:

我有一个小问题... 我搜索了访问仅在 bean 的远程接口中声明而不在本地接口中声明的方法之间的本地访问差异...

接口声明(远程或本地)是否确定方法的访问协议?或者 ejb 容器是否理解两个 bean 都在运行同一个 JVM? 有很大的性能差异吗? 你有这方面的消息来源吗?

BR

劳伦特

【问题讨论】:

    标签: performance interface ejb-3.0 local


    【解决方案1】:

    我建议在您的 EJB 容器上对其进行测试以确定。

    也就是说,根据规范(here,第 3.2.3 节)@Remote 接口必须使用按值参数传递,而@Local 假定按引用参数传递。

    这意味着即使客户端和@Remote bean 都在同一个 JVM 上,也会有参数复制的开销。

    这也意味着所有@Remote 参数必须是可序列化的。

    【讨论】:

      【解决方案2】:

      是的,你说得对,@Remote 总是比 @Local 慢,因为它总是有更多的工作要做。

      将 bean 的接口暴露为 @Local 和 @Remote 的问题(以及规范说它很少见的原因)是参数和返回值语义不清楚。例如,如果你有一个方法:

      List filter(List arg);
      

      ...如果 bean 通过修改参数来实现这个方法,那么客户端必须非常小心地确保在调用方法之前复制对象(@Local)或者避免浪费地复制对象,如果它会自动完成(@Remote)。此外,bean 必须小心不要将可变状态从@Local 接口传递给它的调用者。虽然 List 的情况可能很清楚,但对于像 java.util.Date 这样有问题的 Serializable 或者 bean 是否想要返回“常量”数组,情况可能不太清楚。

      【讨论】:

        【解决方案3】:

        所以如果我创建一个没有本地接口的 bean,同一个 ejb 容器中的任何 bean 都会因为开销而变慢? 因此,如果有本地访问,最好总是声明一个本地接口,即使这个本地接口“只是”远程接口的副本。

        我说的对吗?

        这很奇怪,因为在您提到的源代码中(JSR 220:Enterprise JavaBeansTM,版本 3.0 EJB 核心合同和要求) “虽然可以为企业 bean 提供远程客户端视图和本地客户端视图,但更典型的是只提供其中一个。”

        【讨论】:

          【解决方案4】:

          我在自己的电脑上尝试了两个接口(一个本地接口,另一个远程接口),声明的方法相同。

          包计算; 导入javax.ejb.Remote;

          @远程 公共接口 CalculatorRemote {

          public int add(int a, int b);
          public int sub(int a, int b);
          

          }

          在另一个 bean 中,我注入两个接口并使用它们:

          @EJB
          public CalculatorRemote myRemoteCalc;
          
          @EJB
          public CalculatorLocal myLocalCalc;
          public String fastest(int iter){
              myRemoteCalc.add(5,6);
              myLocalCalc.add(5,6);
          
              long inittimeLocal=System.currentTimeMillis();
              for(int j = 0; j<iter; j++){
                  myLocalCalc.sub(28, 26);
                  myLocalCalc.add(134778, 1234);
              }
              long LocalTime=System.currentTimeMillis()-inittimeLocal;
          
              long inittimeRemote=System.currentTimeMillis();
              for(int i = 0; i<iter; i++){
                  myRemoteCalc.sub(28, 26);
                  myRemoteCalc.add(134778, 1234);
              }
              long RemoteTime=System.currentTimeMillis()-inittimeRemote;
          
              if(LocalTime>RemoteTime){
                  return "Local slower than Remote " + (LocalTime-RemoteTime) + " ms difference with remote processing in "+ RemoteTime + "ms and local processing in"+ LocalTime + " ms. ";
              }
              return "Remote slower than Local " + (RemoteTime-LocalTime) + " ms difference with remote processing in "+ RemoteTime + "ms and local processing in"+ LocalTime + " ms. " ;
          }
          

          当我以最快的速度调用该方法(用于确定远程或本地调用中的哪一个最快)时,结果每次都会给出两种访问方法之间的时间因子 5。

          这里是输出:

          它为 200000 次迭代提供了以下输出:

          远程慢于本地 46 015 毫秒,远程处理 58 609 毫秒,本地处理 12 594 毫秒。

          以及 100000 次迭代的以下输出: 远程慢于本地 23 406 毫秒,远程处理 29 609 毫秒,本地处理 6 203 毫秒。

          以下输出为 1000

          远程比本地慢 219 毫秒,远程处理 297 毫秒,本地处理 78 毫秒。

          这很奇怪,SUN 在他提到的部分末尾几乎建议我们只使用 Gregory 源代码中的一种类型的接口: 虽然可以为企业 bean 提供远程客户端视图和本地客户端视图,但更典型的是只提供其中一个。

          在这种情况下,只有远程访问,调用会很慢,没有人会得到本地快速访问的优势。

          我认为任何 bean 都应该有一个本地接口,其中包括远程接口的方法。远程接口方法将是本地接口方法的子集。有了这个,我们可以确保以正常方式为远程客户端提供服务,而以快速方式为本地客户端提供服务。

          他们这么说只是为了鼓励我们为内部和外部的东西提供不同的 bean 吗?还是因为在更复杂的方法中,本地和远程访问会有很大差异?

          【讨论】:

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