- 浏览: 208616 次
- 性别:
- 来自: 杭州
最新评论
-
李嘉图0624:
第一段代码就出错了,少了g.close();不关闭的话,也没有 ...
Jackson 入门 -
daichangfu:
不光是生僻字需要,正常的也需要啊。
解决Java应用在Linux下无法正常水印生僻字 -
yaoweinan:
不错
JGroup配置笔记 -
learnworld:
grandboy 写道我想json的数据多一些对于数据绑定回j ...
Jackson 入门 -
grandboy:
我想json的数据多一些对于数据绑定回javabean时不会出 ...
Jackson 入门
I’ve come across a lot of business logics in my company that take advantage of the RMI remoting technology. It’s said that the performance of RMI is not only poor, but also is too heavy. However some serious articles and benchmark tests argue that it’s not bad. And I also did some simple performance tests among some remoting technologies, and the result reveals RMI is the best at least in the LAN.
The following is a summary about the most important skills that can promote the speed of RMI as well as a personal RMI debugging logic.
Externalizable instead of Serializable
Default Serialization is slow and we should use the Externalizable interface to transfer only those necessary properties and fields over the network to reduce the network traffic and response time.
Here’s an example:
public class SerializedClass implements Serializable { private String aString; private int anIntA; private int anIntB; private float[] floatArray; private Dimension dimensionA; private Dimension dimensionB; // No more code related to serialization! : : public class ExternalizedClass implements Externalizable { private String aString; private int anIntA; private int anIntB; private float[] floatArray; private Dimension dimensionA; private Dimension dimensionB;
public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(aString); out.writeInt(anIntA); out.writeInt(anIntB); out.writeObject(floatArray); out.writeObject(dimensionA); out.writeObject(dimensionB); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { aString = (String)in.readObject(); anIntA = in.readInt(); anIntB = in.readInt(); floatArray = (float[])in.readObject(); dimensionA = (Dimension)in.readObject(); dimensionB = (Dimension)in.readObject(); } // Etc.
|
The above code snippet is quoted from Accelerate your RMI programming. If you’re interesting in the benefit that gained from this method, I suggest you read the article.
Use null for default objects
Java would not transfer the null value over the network and this could also make your object compact.
Use the transient key word
If you are really sure about a property that is not valuable for you remote user, then make it a local property with the transient key word. Use the transient keyword to define fields to avoid having those fields serialized. Examine serialized objects to determine which fields do not need to be serialized for the application to work.
Specify a specific IP address to bind the remote service
We need to bind our remote service to a specific IP address from time to time if there are multiple network interfaces on a server. And as now we are more often using Spring to expose our remote service, I will show the Spring way to specify the IP address to bind to at run time.
<bean id="xxxRMIServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter"> <property name="serviceName"> <value>BillingRemoteService</value> </property> <property name="service"> <ref bean="billingRMIService"/> </property> <property name="serviceInterface"> <value>com.xxx.xxx.BillingRemoteService</value> </property> <property name="registryPort"> <value>1199</value> </property> <property name="registryHost"> <value>192.168.21.161</value> </property> </bean>
How to debug
We’ve been stuck in the RMI in our products’ previous development version and have limited knowledge about RMI, and hereafter we could only fix some problems by our experience. We want to know how many remote services have been registered, want to know if a particular service is up and running and list the methods on a service, etc.
Here’s the interface:
package com.bee.fw.rmi; import java.lang.reflect.InvocationTargetException; import java.rmi.Remote; /** * @author Ginge */ public interface RmiServiceManager { /** * List all the registered Remote Services bound to the port at the host * @param host * @param port * @return */ String [] listRemoteObjects(String host, int port); /** * Find the registered Remote Service bound to the port at the host * @param host * @param port * @param remoteObject * @return * @throws RemoteObjectNotFoundException */ Remote findRemoteObjects(String host, int port, String remoteObject) throws RemoteObjectNotFoundException; /** * Invoke the remote method on the remote Object * @param host * @param port * @param remoteObject * @param methodName * @param args * @return * @throws RemoteObjectNotFoundException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ Object invokeRemoteMethod(String host, int port, String remoteObject, String methodName, Object ...args) throws RemoteObjectNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException ; }
And the implementation, it requires at least Spring 2.0.5:
package com.bee.fw.rmi; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.rmi.AccessException; import java.rmi.NotBoundException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.SimpleTypeConverter; /** * * @author Ginge * */ public class RmiServiceManagerImpl implements RmiServiceManager { private Log log = LogFactory.getLog(this.getClass()); private SimpleTypeConverter simpleTypeConverter = new SimpleTypeConverter(); private Registry getRegistry(String host, int port) { Registry registry = null; try { if(log.isDebugEnabled()) { log.debug("Locating registry at host["+host+"] on port["+port+"]"); } registry = LocateRegistry.getRegistry(host, port); } catch (RemoteException e) { if (log.isErrorEnabled()) { log.error("Failed to locate Registry at host [" + host + "] on port [" + port + "]", e); } } if(log.isDebugEnabled()) { log.debug("Registry found."); } return registry; } @Override public Remote findRemoteObjects(String host, int port, String remoteObject) throws RemoteObjectNotFoundException{ Registry registry = this.getRegistry(host, port); if (registry != null) { try { return registry.lookup(remoteObject); } catch (AccessException e) { if (log.isErrorEnabled()) { log.error("RMI object ["+remoteObject+"] Access denied.",e ); } } catch (RemoteException e) { if (log.isErrorEnabled()) { log.error("RMI object ["+remoteObject+"] RemoteException.", e); } } catch (NotBoundException e) { if (log.isErrorEnabled()) { log.error("RMI object ["+remoteObject+"] NotBoundException.",e ); } } } throw new RemoteObjectNotFoundException("Remote Object ["+remoteObject+"]"); } private Method findMethodWithName(Remote remote, String methodName, int argsLength) throws NoSuchMethodException { Class objectClass = remote.getClass(); Method [] methods = objectClass.getMethods(); for(Method method : methods) { if(method.getName().equalsIgnoreCase(methodName) && method.getParameterTypes().length == argsLength) { return method; } } throw new NoSuchMethodException("No such Method ["+methodName+"]" ); } private Object invokeMethod(Object obj, Method method, Object ...args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { Class [] parameterTypes = method.getParameterTypes(); if((args != null && args.length != parameterTypes.length) || (parameterTypes.length == 0 && args != null)) { throw new IllegalArgumentException("The input args length doesn't match the expected parameter length."); } List<Object> arguments = new ArrayList<Object>(); if(args != null) { for(int i = 0; i < parameterTypes.length; i ++) { Object converted = simpleTypeConverter.convertIfNecessary(args[i], parameterTypes[i]); arguments.add(converted); } } return method.invoke(obj, arguments.toArray(new Object[arguments.size()])); } @Override public String [] listRemoteObjects(String host, int port) { // TODO Auto-generated method stub Registry registry = this.getRegistry(host, port); if (registry != null) { try { return registry.list(); } catch (AccessException e) { if (log.isErrorEnabled()) { log.error("RMI Access denied, failed to list.",e ); } } catch (RemoteException e) { if (log.isErrorEnabled()) { log.error("RMI RemoteException.", e); } } } return null; } @Override public Object invokeRemoteMethod(String host, int port, String remoteObject, String methodName, Object... args) throws RemoteObjectNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { Remote remote = this.findRemoteObjects(host, port, remoteObject); Method method = this.findMethodWithName(remote, methodName, (args != null ? args.length : 0)); return this.invokeMethod(remote, method, args); } }
It’s very easy to write a utility tool to debug RMI using the above code by now. And here’s the screen snapshot of my tools.
Resources
1) Accelerate your RMI programming
3) Java remoting protocol benchmarks
4) Middleware remoting protocol migration
评论
Any one who wants to view the outcome of my tool please go to see my photo album.
发表评论
-
开发新手通用代码问题
2011-06-04 06:32 13168最近辅导黄埔的同学进行开发,发现了一些问题,隐约看到当年自己写 ... -
jmockit 的使用系列
2010-12-13 21:30 94171. 入门 2. 完整的Mock步骤 ... -
jmockit 的使用示例-02完整的Mock步骤
2010-12-13 21:11 4875package jmockit.sample; impo ... -
jmockit 的使用示例-03全部mock的?
2010-12-13 21:11 3644package jmockit.sample; impo ... -
jmockit 的使用示例-04静态部分mock示例
2010-12-13 21:10 3862package jmockit.sample; impo ... -
jmockit 的使用示例-06私有成员的Mock
2010-12-13 21:10 7652目标测试代码 package jm ... -
jmockit 的使用示例-07私有静态成员Mock
2010-12-13 21:09 4690目标测试代码 package jmockit.target ... -
jmockit 的使用示例-09构造方法也可以Mock?基于状态的Mock?
2010-12-13 21:07 10376目标测试代码 package jmockit.target ... -
jmockit 的使用示例-10另一种基于状态的Mock,随穿随脱?
2010-12-13 21:07 2705目标测试代码 package jm ... -
jmockit 的使用示例-11不是吧,还能访问实际被Mock的对象?
2010-12-13 21:07 3231目标测试代码 package jmockit.target ... -
jmockit 的使用示例-07私有静态成员Mock
2010-12-13 20:40 5889目标测试代码 package jmockit.target ... -
jmockit 的使用示例-02完整的Mock步骤
2010-12-13 20:31 1462package jmockit.sample; impo ... -
开放的心态
2010-10-02 13:56 981今天看李笑来的《把时间当作朋友》,看到一句话,“我们的大脑 ... -
Jackson 入门
2010-09-15 07:17 6492同事的一些测试结果看来,Jackson在处理Json方面性能相 ... -
解决Java应用在Linux下无法正常水印生僻字
2010-04-10 13:46 5616昨天接到一个投诉,说是他的水印是一个方框。刚开始还以为是程序出 ... -
同学们,秒投简历啦!
2010-03-12 23:51 221公司业务急速扩张,急需有才能的同学加入到我们的行列中, ... -
反编译工具
2009-12-31 20:54 1132追查JVM崩溃过程中使用到的反编译工具,其中beanutils ... -
追查JVM崩溃
2009-12-31 20:25 2240JDK升级到1.6后,服务器集群经常崩溃,后来把VM的参 ... -
普通用户下实现Apache 2.2.14与jboss-5.1.0.GA集成
2009-11-29 23:05 2766Apache与jboss集成,实际是apache与tomcat ... -
swt 笔记
2009-11-27 00:24 891http://www.ibm.com/developerwor ...
相关推荐
java rmi java rmijava rmi javajava rmi java rmi rmi
RMI简单实例RMI简单实例RMI简单实例
完整的Rmi调用示例,极难得的Rmi应用示例
rmi的详细例子,rmi的详细用法,一看就懂
RMI 规范 RMI 详细介绍 共10章
RMI教程 Java RMIRMI教程 Java RMIRMI教程 Java RMIRMI教程 Java RMIRMI教程 Java RMI
rmi小程序,RMI文档,为RMI初学者使用
RMI远程方法调用RMI远程方法调用RMI远程方法调用RMI远程方法调用RMI远程方法调用
1. Unpack RMI.rar and put the package "features" and "plugins" under the package "net.genady.rmi_2.0.2.1" to <%eclipse%> directory; 2. Copy rmi.jar and lic.jar under the package "crack" to ...
《Java RMI》一书的英文版本,With Java RMI, you'll learn tips and tricks for making your RMI code excel. This book provides strategies for working with serialization, threading, the RMI registry, ...
Spring-RMI (RMI调用, HTTP调用) 本人测试过了
本项目使用socket直接发送数据包来攻击rmi,通过反序列化攻击rmi,双击直接运行,对1099端口的rmi服务直接进行漏洞检测。
java rmi上传文件 在这次的项目中,对于客户端与服务器之间的通信,想了许多办法,由于做的是富客户端应用,最终将技术选定在了RMI和Java-sockets两种之间,其中RMI的灵活性不高,客户端和服务器端都必须是java编写...
Weblogic Server与RMI RMI的使用介绍
Java编程rmi实例,给出远程方法调用技术在java方面的具体例子。
java RMI
spring RMI 简单例子
web服务器 RMI meeting sokect
分布式实验报告RMI.docx
Java中RMI的实现机制Java中RMI的实现机制Java中RMI的实现机制Java中RMI的实现机制