- 浏览: 212089 次
- 性别:
- 来自: 杭州
最新评论
-
李嘉图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 14163最近辅导黄埔的同学进行开发,发现了一些问题,隐约看到当年自己写 ... -
jmockit 的使用系列
2010-12-13 21:30 94751. 入门 2. 完整的Mock步骤 ... -
jmockit 的使用示例-02完整的Mock步骤
2010-12-13 21:11 4924package jmockit.sample; impo ... -
jmockit 的使用示例-03全部mock的?
2010-12-13 21:11 3684package jmockit.sample; impo ... -
jmockit 的使用示例-04静态部分mock示例
2010-12-13 21:10 3908package jmockit.sample; impo ... -
jmockit 的使用示例-06私有成员的Mock
2010-12-13 21:10 7751目标测试代码 package jm ... -
jmockit 的使用示例-07私有静态成员Mock
2010-12-13 21:09 4768目标测试代码 package jmockit.target ... -
jmockit 的使用示例-09构造方法也可以Mock?基于状态的Mock?
2010-12-13 21:07 10456目标测试代码 package jmockit.target ... -
jmockit 的使用示例-10另一种基于状态的Mock,随穿随脱?
2010-12-13 21:07 2736目标测试代码 package jm ... -
jmockit 的使用示例-11不是吧,还能访问实际被Mock的对象?
2010-12-13 21:07 3279目标测试代码 package jmockit.target ... -
jmockit 的使用示例-07私有静态成员Mock
2010-12-13 20:40 5942目标测试代码 package jmockit.target ... -
jmockit 的使用示例-02完整的Mock步骤
2010-12-13 20:31 1492package jmockit.sample; impo ... -
开放的心态
2010-10-02 13:56 1020今天看李笑来的《把时间当作朋友》,看到一句话,“我们的大脑 ... -
Jackson 入门
2010-09-15 07:17 6541同事的一些测试结果看来,Jackson在处理Json方面性能相 ... -
解决Java应用在Linux下无法正常水印生僻字
2010-04-10 13:46 5720昨天接到一个投诉,说是他的水印是一个方框。刚开始还以为是程序出 ... -
同学们,秒投简历啦!
2010-03-12 23:51 221公司业务急速扩张,急需有才能的同学加入到我们的行列中, ... -
反编译工具
2009-12-31 20:54 1195追查JVM崩溃过程中使用到的反编译工具,其中beanutils ... -
追查JVM崩溃
2009-12-31 20:25 2282JDK升级到1.6后,服务器集群经常崩溃,后来把VM的参 ... -
普通用户下实现Apache 2.2.14与jboss-5.1.0.GA集成
2009-11-29 23:05 2804Apache与jboss集成,实际是apache与tomcat ... -
swt 笔记
2009-11-27 00:24 929http://www.ibm.com/developerwor ...
相关推荐
RMI(Remote Method Invocation,远程方法调用)是Java平台中的一个重要特性,它允许Java对象在不同的Java虚拟机之间进行通信,实现分布式计算。RMI是Java开发分布式应用程序的基础,尤其在构建分布式服务和微服务...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许Java对象在不同的网络环境中进行交互,就像它们在同一个进程内一样。RMI是Java在分布式系统领域的核心特性,极大地...
根据提供的文件信息,我们可以深入探讨Java RMI(Java Remote Method Invocation)的相关知识点,包括其概念、原理、体系结构以及一个具体的示例。 ### RMI的概念 RMI是一种Java技术,它允许开发者创建分布式应用...
Java RMI(远程方法调用)是Java编程语言中的一项核心技术,自JDK 1.1版本起就被引入,用于构建分布式系统。RMI允许Java对象在不同的Java虚拟机(JVMs)之间进行交互,仿佛这些对象是在同一台机器上一样。这种技术的...
### Java RMI (Remote Method Invocation) 概念与实践 #### 一、Java RMI简介 Java RMI(Remote Method Invocation)是一种允许调用不同Java虚拟机(JVM)上方法的机制。这些JVM可能位于不同的机器上,也可能在同一...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行远程对象的调用。RMI使得开发者可以像调用本地对象一样调用网络上的对象,极大地简化了...
Java Remote Method Invocation (RMI) 是Java平台提供的一种分布式计算技术,它允许Java对象在不同的网络环境中进行交互,实现远程方法调用。本压缩包文件"rmi-code"包含了一个完整的RMI测试代码示例,适合在Linux和...
Java RMI (Remote Method Invocation) 是一种用于在Java应用程序之间进行远程通信的技术。为了提高RMI通信的安全性,我们可以使用SSL (Secure Sockets Layer) 或其后继者TLS (Transport Layer Security) 进行加密。...
Spring Remote Method Invocation(RMI)是Java平台上的一个远程对象调用框架,它允许一个Java对象在一台机器上执行,并且被另一台机器上的客户端调用。在这个"SpringRMI小例子"中,我们将深入探讨如何利用Spring...
在Spring框架中,远程方法调用(Remote Method Invocation, RMI)是一种使应用程序能够通过网络调用另一个JVM上的对象方法的技术。RMI是Java平台的一部分,它允许开发者创建分布式应用,使得对象可以像调用本地方法...
分布式实验报告 RMI.docx 本实验报告主要介绍了 Java RMI(Remote Method Invocation,远程方法调用)的基本概念和实现步骤。RMI 是一种分布式对象通讯机制,允许运行在一个 Java 虚拟机的对象调用运行在另一个 ...
**RMI原理及应用详解** 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种分布式计算技术,允许在不同的Java虚拟机(JVM)之间进行对象方法的透明调用。RMI的核心思想是使Java对象能够跨越...
Ehcache RMI Replicated Cluster 是一种分布式缓存解决方案,它使用远程方法调用(RMI)技术在多个节点之间复制数据,以实现高可用性和负载均衡。在大型分布式系统中,缓存是提高应用程序性能的关键组件,因为它可以...
Spring RMI(Remote Method Invocation)是Java平台上的远程方法调用技术,结合Spring框架的特性,使得在分布式系统中调用远程服务变得更加便捷。在这个简单的例子中,我们将深入理解Spring RMI的工作原理以及如何...
**基于JAVA RMI的聊天室** Java Remote Method Invocation(RMI)是Java平台提供的一种用于在分布式环境中调用远程对象的方法。在这个“基于JAVA RMI的聊天室”项目中,开发者利用RMI技术构建了一个简单的多用户...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛这些对象都在同一台机器上。RMI是Java网络编程的重要组成部分,使得开发...
Java RMI(Remote Method Invocation)技术是Java平台中用于分布式计算的一种机制,它允许一个Java对象调用远程计算机上的另一个Java对象的方法。在本案例中,“java RMI技术实现的网络聊天室”是一个使用RMI构建的...
本项目实例是基于RMI技术实现的一个服务器端程序,名为"RMIServer",提供了远程服务的接口和实现,下面将详细介绍RMI的基本概念、工作原理以及如何通过这个项目实例来学习和应用RMI。 1. **RMI基本概念**: - **...
Spring RMI服务是一种在Java平台上实现远程方法调用(Remote Method Invocation, RMI)的技术,它允许分布式系统中的不同组件通过网络进行通信。在Spring框架的支持下,我们可以更方便地将服务发布为RMI服务,使得...