我有一个小问题...我搜索访问仅在 bean 的远程接口中声明的方法与不在本地接口中声明的方法之间的本地访问差异...
接口声明(远程或本地)是否确定方法的访问协议?或者 ejb 容器是否理解两个 bean 都在运行同一个 JVM?有很大的性能差异吗?你有这方面的任何消息来源吗?
BR的
洛朗
我有一个小问题...我搜索访问仅在 bean 的远程接口中声明的方法与不在本地接口中声明的方法之间的本地访问差异...
接口声明(远程或本地)是否确定方法的访问协议?或者 ejb 容器是否理解两个 bean 都在运行同一个 JVM?有很大的性能差异吗?你有这方面的任何消息来源吗?
BR的
洛朗
我建议在您的 EJB 容器上对其进行测试以确定。
也就是说,根据规范(此处,第 3.2.3 节)@Remote 接口必须使用按值参数传递,而 @Local 假定按引用参数传递。
这意味着即使客户端和@Remote bean 都在同一个 JVM 上,也会有参数复制的开销。
这也意味着所有@Remote 参数都必须是可序列化的。
是的,你说得对,@Remote 总是比@Local 慢,因为它总是有更多的工作要做。
将 bean 的接口暴露为 @Local 和 @Remote 的问题(以及规范说它很少见的原因)是参数和返回值语义不清楚。例如,如果您有一个方法:
List filter(List arg);
...如果 bean 通过修改参数来实现这个方法,那么客户端必须非常小心地确保在调用方法之前复制对象(@Local)或者避免浪费地复制对象,如果它会自动完成( @偏僻的)。此外,bean 必须小心不要将可变状态从@Local 接口传递给它的调用者。虽然 List 的情况可能很清楚,但对于像 java.util.Date 这样有问题的 Serializable 或者 bean 是否想要返回“常量”数组,情况可能不太清楚。
因此,如果我创建一个没有本地接口的 bean,同一个 ejb 容器中的任何 bean 都会因该开销而变慢?因此,如果有本地访问,最好总是声明一个本地接口,即使这个本地接口“只是”远程接口的副本。
我对吗?
这很奇怪,因为在您提到的源代码中(JSR 220:Enterprise JavaBeansTM,版本 3.0 EJB 核心合同和要求)“虽然可以为企业 bean 提供远程客户端视图和本地客户端视图,但更典型的是只有一个或另一个将提供。”
我在自己的电脑上尝试了两个接口(一个是本地的,另一个是远程的),声明的方法相同。
包计算;导入javax.ejb.Remote;
@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 吗?还是因为在更复杂的方法中本地和远程访问会有很大差异?