似乎“ Spring Exporter”除了方法的值之外,还返回完整的类路径(文件的URI): wireshark screenshot
在此示例应用程序中,大约需要2KB。但实际上,它需要十个以上的8KB tcp片段,并导致大量的延迟。因此,我正在寻找一种解决方案,以防止传递这些额外的数据。
服务器端配置XML:
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<bean id="calculationBean" class="com.misc.poc.rmi.CalculationImpl"/>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="service" ref="calculationBean"/>
<property name="serviceInterface" value="com.misc.poc.rmi.Calculation"/>
<property name="serviceName" value="CalculationService"/>
<property name="servicePort" value="2000"/>
<property name="registryPort" value="1999"/>
</bean>
</beans>
客户端配置XML:
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<bean id="calculationBean" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://192.168.100.94:1999/CalculationService"/>
<property name="serviceInterface" value="com.misc.poc.rmi.Calculation"/>
<property name="lookupStubOnStartup" value="false"/>
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
</beans>
一些相关的类:
public interface Calculation {
int cube(int number);
Info greeting(String name);
}
public class Info implements Serializable {
private String title;
private String desc;
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getDesc() { return desc; }
public void setDesc(String desc) { this.desc = desc; }
}
public class CalculationImpl implements Calculation {
@Override
public int cube(int number){
return number*number*number;
}
@Override
public Info greeting(String name) {
Info res = new Info();
res.setTitle(name);
res.setDesc("Hello");
return res;
}
}
RMI ReturnData:
E uüg@@7ÐðiøtC}þz8^j
¾¾〜Q¬íw_`2hå{{R4srcom.misc.poc.rmi.Info ^èù¶é¶××LdesctLjava / lang / String; Ltitleq〜tÉfile:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB-INF / classes /文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB -INF / lib / spring-security-config-3.2.5.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB-INF /lib/aspectjweaver-1.8.9.jar文件:/home/user/masoud/jobs/huge-marshal/huge-marshal-app/web-server/target/server/WEB-INF/lib/spring-web-4.3 .10.RELEASE.jar文件:/home/user/masoud/jobs/huge-marshal/huge-marshal-app/web-server/target/server/WEB-INF/lib/aopalliance-1.0.jar文件:/ home /user/masoud/jobs/huge-marshal/huge-marshal-app/web-server/target/server/WEB-INF/lib/common-1.0.jar文件:/ home / user / masoud / jobs / huge-marshal /huge-marshal-app/web-server/target/server/WEB-INF/lib/commons-logging-1.2.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web -服务器/目标/服务r / WEB-INF / lib / spring-security-taglibs-3.2.5.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB-INF / lib / spring-jdbc-4.3.10.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB-INF / lib / spring-core-4.3.10.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB-INF / lib / spring- security-core-3.2.5.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app / web-server / target / server / WEB-INF / lib / spring-expression- 4.3.10.RELEASE.jar文件:/home/user/masoud/jobs/huge-marshal/huge-marshal-app/web-server/target/server/WEB-INF/lib/spring-security-acl-3.2。 5.RELEASE.jar文件:/home/user/masoud/jobs/huge-marshal/huge-marshal-app/web-server/target/server/WEB-INF/lib/spring-context-4.3.10.RELEASE。 jar文件:/home/user/masoud/jobs/huge-marshal/huge-marshal-app/web-server/target/server/WEB-INF/lib/spring-beans-4.3.10.RELEASE.jar文件:/主页/用户/ masoud /工作/巨大的火星hal / huge-marshal-app / web-server / target / server / WEB-INF / lib / spring-security-web-3.2.5.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal-app /网络服务器/目标/服务器/WEB-INF/lib/spring-tx-4.3.10.RELEASE.jar文件:/ home / user / masoud / jobs / huge-marshal / huge-marshal- app / web-server / target / server / WEB-INF / lib / spring-aop-4.3.10.RELEASE.jarxptHellotGholi
答案 0 :(得分:0)
我的理解是,此JAR列表在RMI响应中作为“类注释”发送。
我发现使用https://github.com/NickstaDB/SerializationDumper上的SerializationDumper
工具。
(提示:我必须使用dd conv=swab <data.orig >data.swapped
从Wireshark的转储中交换字节顺序,以便将其馈送到SerializationDumper -r
。)
....
classAnnotations
TC_STRING - 0x74
newHandle 0x00 7e 00 01
Length - 21685 - 0x54 b5
Value - file:/app/my-rmi-server-app.jar file:/tmp/cache/repository/org/springframework/boot/spring-boot-starter-web/2.1.4.RELEASE/spring-boot-starter-web-2.1.4.RELEASE.jar file:/tmp/maven/repository/org/springframework/boot/spring-boot-starter/2.1.4.RELEASE/spring-boot-starter-2.1.4.RELEASE.jar ...
我不是RMI专家,但是对我来说,这还不是很清楚,RMI服务器上的这些路径对显然无法访问这些路径的RMI客户端有什么用?!?
无论如何,此类注释值是在https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/sun/rmi/server/LoaderHandler.java#L194中生成的。
该算法利用所谓的类/代码库加载器来确定该值必须是什么。
就我而言,我使用Spring Boot Thin Launcher打包和运行我的应用程序,因此可能会对这种算法产生影响。
我发现总是发送 empty 类注释的方法是用我自己的方法覆盖默认的RMIClassLoaderSpi
:
package my.app;
import java.net.MalformedURLException;
import java.rmi.server.RMIClassLoader;
import java.rmi.server.RMIClassLoaderSpi;
public class LeanRMIClassLoaderSpi extends RMIClassLoaderSpi {
private final RMIClassLoaderSpi delegate;
public LeanRMIClassLoaderSpi() {
this.delegate = RMIClassLoader.getDefaultProviderInstance();
}
@Override
public Class<?> loadClass(String codebase, String name,
ClassLoader defaultLoader) throws MalformedURLException,
ClassNotFoundException {
return delegate.loadClass(codebase, name, defaultLoader);
}
@Override
public Class<?> loadProxyClass(String codebase, String[] interfaces,
ClassLoader defaultLoader) throws MalformedURLException,
ClassNotFoundException {
return delegate.loadProxyClass(codebase, interfaces, defaultLoader);
}
@Override
public ClassLoader getClassLoader(String codebase)
throws MalformedURLException {
return delegate.getClassLoader(codebase);
}
@Override
public String getClassAnnotation(Class<?> cl) {
return null;
}
}
必须将Java系统属性java.rmi.server.RMIClassLoaderSpi
设置为my.app.LeanRMIClassLoaderSpi
,https://github.com/openjdk/jdk/blob/master/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java中的代码才能将其提取。
而且,您的RMI流量已大大减少-在我看来,该应用程序仍然可以正常工作。