- 浏览: 97579 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
chifanbua:
我基本上在iteye上很少留言的 不过你的这个写的确实不错 用 ...
Oracle decode函数说明 -
shaoxuexue86:
谢谢啊
RMI 开发步骤 -
huxiaojun_198213:
RMIRegistHelper只是负责注册远程对象,与客户端所 ...
RMI 开发步骤 -
shaoxuexue86:
请问客户端程序ClientTest 与 RMIRegistHe ...
RMI 开发步骤 -
huxiaojun_198213:
本章节可能有一些细节方面翻译得不是很好,有出入的地方,还请各 ...
RMI动态类加载
RMI运行时环境在客户端和服务端都扮演了重要的角色.在这种架构中,stub达到了三种目的:
1.它是序列化的,通过网络可以从服务端向客户端发送.也可以包含数据使其可以稳定地向服务端发送消息.
2.它是服务端的代理,客户端可以把stub当作是服务器.
3.它可以池化socket.每次方法调用的时候,stub就向RMI运行时请求一个特别服务的连接.这使得RMI可以在多个请求之间重用sockets(即可以共享socket).
在多个请求之间重用socket,可能会导致下面的问题:
如果一个socket被多个客户端的stubs重用,它们每一个都向不同的服务器发送了消息,那么这些消息之间应该有某种意义上的区别.那么应该如何来区分呢?
在RMI中,这种区分是通过使用java.rmi.server包下的ObjID类来进行的.
ObjID在javadoc中是这样定义的:
ObjID被唯一用来标识远程对象.每一个标识符都包含一个对象数(类型为long)和一个地址空间标识符(类型为UID,对于特定主机是唯一的).
对象标识符是在远程对象被导出时分配的.如果java.rmi.server.randomIDs属性设置为true的话,通过无参构造函数创建的ObjID对象的64位对象树将包含一个加密的强随机数.
因此,ObjID的实例可以唯一地标识服务器JVM中的特定服务.同时,ObjID类实现了序列化接口,因此,在每个远程方法调用时,其实例都可以被序列化.
在服务端,RMI运行时使用ObjID的反序列化来找出远程方法调用将要调用的skeleton.
RMI是怎样解决引导问题的?
大部分服务器在过去的使用中都是通过随机分配ObjID的实例来处理的.在其实例中有三种保留的标识符:ACTIVATOR_ID(),DGC_ID和REGISTRY_ID.
这三种IDs分别对应RMI提供的三种服务:激活构架,分布式垃圾收集和RMI注册表.
为了能够完全解决引导问题,RMI注册表需要预知的一个唯一标识符.
当一个客户端第一次试图连接RMI注册表的时候,除非它知道与服务器相关的对象标识符,否则此客户端就不能向服务器端发送消息.
也就是说,因为服务器端的RMI运行时需要一个ObjID的实例来决定使用哪个合适的服务器来响应客户端的请求,客户端为了能连接注册表,它必须要知道运行在服务器JVM中注册表的ObjID.
为了解决这个问题,RMI的设计者们定义了ObjID的保留实例-如果一个注册表运行在一个虚拟机中,它就使用REGISTRY_ID.否则,不允许任何服务器使用REGISTRY_ID.
这解决了RMI引导问题.Naming的静态方法接受一个主机和端口;构建stub时仅需的附加信息是stub连接服务器的Object ID.
由于注册表总是使用REGISTRY_ID,注册表的stub在连接注册表之前总是能在客户端被完全地构建.
这种策略也意味着,一个JVM只能导出一个注册表,这是因为不能在多个服务器间共享ObjID.
分布式垃圾收集
另一个固定的标识符是DGC_ID.这是内置于RMI中的关于分布式垃圾收集的对象标识符.
垃圾收集的基本想法是定义一系列的可到达对象,并丢弃那么不可达对象.可达对象是递归定义的:
1.每个活动线程当前都处在一个方法中或处在未知对象的实例中.那么线程所在的实例就是可到达的.
2.每个线程能够立即找到被方法级变量和实例字段引用的对象,这些对象也是可到达的.
3.从这些立即可访问的对象(此对象引用了其他对象),能够访问到其他可到达的对象.
诸如此类,一般来说,如果一个线程,从它当前位置开始,能够最终找到某个对象,那么此对象就是可达的.
在单个JVM中垃圾收集机制工作得很好.但在分布式系统中,stub问题将会出现.如果一个客户端拥有一个服务器端的引用 ,那么服务器应该是可到达的.
由于所有的stub真正拥有的是一个ObjId的实例,这意味着RMI运行时必须保持所有活动服务器的引用.为了垃圾回收,客户端的RMI运行时必须以某种方法让服务端运行时知道stub何时不再被使用.
最明显的方式是使用分布式引用计数.也就是,强制客户端stub发送两条额外的信息给服务器.
当stub被实例化发送一条消息,以便让服务器知道有一个活动的客户端(计数器加1).当stub释放的时候,再发送一条消息,以通知服务器客户端已经使用完了服务端(计数器减1).
在这种方案中,最脆弱的是第一步.下面的每一个问题都可能增加计数的困难度:
1.客户端垃圾收集算法不能保证立即回收stub.如果客户端的内存充裕,且正忙于处理具有高优先级的任务,那么垃圾收集暂时可能不会发生.在这段时期之内,客户端将隐含地强制服务端保持那些没有必要的资源.
2.客户端可能会崩溃(crash).假设一个客户端崩溃了的话,那么第二条消息将无法发送,这样就会导致服务端引用计数无法变为0,且RMI运行时将永远保持服务对象为活动状态.
3.可能会出现网络问题.即使客户端是好的,且能发送消息,但网络问题也可能出现.在这种情况下, RMI运行时决不将服务端引用减为0,这样就导致了服务端对象一直处于活动状态.
在这三个问题中,第一个问题是不可能解决的.Java语言规范明确的表明本地垃圾收集是不可依赖的.垃圾收集将来可能发生,但没有一种方式来强制它在某一时间段内发生.
在垃圾收集运行之前,没有一种方法知道一个stub变成了不可引用,因此任何一个分布式引用计数架构将不得不接受第一问题的现实.
第二和第三个问题可以通过将所有分布式引用作为临时引用来消除.其基本思想被称为租赁.基本算法如下:
1.客户端调用服务器并请求一段时间的租期.
2.服务端响应,并同意一段时间的租期(不一定与客户端请求的租期相同)
3.在这段时间之内,分布式引用计数将包含客户端(即增加计数1)
4.当租期期满的时候,如果客户端请求没有延长期限的话,则分布式应用计数将会自动减少(即减少计数1).
只要stub没有被垃圾回收的话,客户端就会自动尝试续期租赁.通过这种算法,可以灵巧地解决第二,第三个问题.
如果客户端崩溃了的话,即客户端就不再运行了,那么客户端就不能再续期租赁,结果就会导致服务器最终将其回收掉.
相似地,如果因网络问题阻止了客户端程序连接服务器,客户端也不会续期到租赁,因此服务端最终也会对其进行垃圾回收.
默认地租期为10分钟,可以通过java.rmi.dgc.leaseValue属性进行设置,时间单位为毫秒.
真实的分布式垃圾收集器
分布式垃圾收集器是一个RMI服务器程序,它实现java.rmi.dgc.DGC接口(此接口继承自java.rmi.Remote接口).此接口只包含两个方法声明:
public void clean(ObjID[] ids,long sequenceNum,VMID vmid,boolean strong)
public Lease dirty(ObjID[] ids,long sequenceNum,Lease lease)
clean()方法是由客户端在不需要服务端引用的时候,由它的运行时调用的.严格来讲,调用clean()方法是没有必要的-客户端运行时可能不续期租赁而达到相同的目的.
但是,租赁应该看作是服务器清理机制的最后一道防线(通过它可以在适当的位置减少网络和客户端失败造成的损害).
客户端运行时可以通过调用dirty()方法来获得一个租赁.不需要直接传递一个VMID(虚拟机ID,即一个JVM的唯一标识符)给dirty()方法,因Lease的实例已经传递了VMID(通过其构造函数可以看出).
注意:对于一个特定的JVM来说,它只能有一个分布式垃圾回收器,其对象标识符为DGC_ID.
Unreferecnced接口
分布式垃圾回收器负责维持租赁.在服务器端,当特定服务器的所有未解决租赁过期的时候,分布式垃圾回收器确保RMI运行时不再保留服务端引用.
因此服务端就可以被回收.在此处理过程中,如果服务端(远程对象)实现了Unreferenced接口,那么服务端在没有多个引用该对象的客户机时接收通知.Unreferenced接口只包含一个方法:
public void unreferenced()
当服务器需要立即释放资源而不是等待垃圾回收发生时,此接口非常重要.同时,它也是一个持久化代码的便利钩子-因为服务端知道不再有远程方法调用,所以它能将状态安全地存储到一个持久化介质(如,一个关系型数据库).
RMI日志
除了分布式垃圾回收之外,RMI运行时也包含广泛的日志,这些日志可以让你跟踪应用程序的行为.RMI中有三种不同的日志类型:标准日志,专门日志(包含5种类型),调试日志
标准日志
标准日志用于在服务端记录方法调用和异常信息.标准日志的使用是很容易的,可以通过设置java.rmi.server.logCalls系统属性(值为boolean类型)来启用或关闭.此属性可通过命令行或程序进行设置.如:
命令行:
程序:
一旦你启用了日志,你可以配置日志的输出目的地.可以通使用java.rmi.server.RemoteServer类的静态方法进行设置:
public static PrintStream getLog()
用于获取当前的日志的流
public static void setLog(OutputStream out)
设置日志的输出流.
缺省情况下,日志系统使用System.err.也就是说,如果你没有设置标准日志输出目的地的话,它将会在System.err上显示.
专门日志
RMI有五种类型的专门日志用于记录运行时的特定方面.这些日志是transport log(传输日志),proxy log(代理日志),loader log(负载日志),DGC log(分布式垃圾回收日志)以及TCP log(tcp日志).
它们均为java.rmi.server.LogStream(此类从JDK1.3版本时已经被废弃)的实例.为了得到与日志相关的LogStream,可以调用其静态方法:public static LogStream log(String name).
一旦你有了LogStream的实例,就可以使用其 setOutputStream()来设置其输出目的地.如:
这些日志通过6个系统属性来操作,每一个属性都接受三个设置:silent(不记录信息),brief(记录少量信息),verbose(记录大量信息),可以使用s,b,v是上述三个值的简写形式.
此6个属性如下:(以下属性因为已被废弃,且属sun公司专有属性,具体含义可查看参考资料)
sun.rmi.server.dgcLevel
sun.rmi.server.logLevel
sun.rmi.loader.logLevel
sun.rmi.transport.logLevel
sun.rmi.transport.tcp.logLevel
sun.rmi.transport.proxy.logLevel
调试日志
同标准日志一样,可以通过设置系统属性sun.rmi.log.debug的boolean值来开启或禁用此功能.但不同于标准日志的是,调试日志总是将信息显示在System.err上.调试日志被用于激活框架的守护线程中.
基本RMI参数
java.rmi.server.randomIDS
其属性值为boolean型.当设置为true时,它强制RMI运行时为新导出的服务对象生成加密的安全对象标识.默认为false.
sun.rmi.server.exceptionTrace
其属性值为boolean型.当其设为true的时候(默认为false),所有的异常将会被打印到System.err上.反之,则不打印.
传输层参数
传输层是底层参数,它能够直接影响RMI底层的sokets的使用和TCP/IP的配置.有三个传输层参数:
sun.rmi.transport.connectionTimeout
用于设置在RMI关闭之前,socket的休眠时间.默认为15秒,在较慢的网络中,应该加大此值。
必须在客户端和服务器端同时设定此值,因为两端都试图重用同一个socket.如果服务端设为60秒的话,客户端设为15秒的话,那么实际上服务端设置的参数将会被客户端参数所否决。
sun.rmi.transport.tcp.readTimeout
设置底层socket读取超时时间,此参数的值实际上只能通过直接传递给socket的方式进行设值(通过socket的setSoTimeOut()).此参数的默认值为2个小时(7200,000毫秒)。
sun.rmi.transport.proxy.connectTimeout
用于设置在两个JVM建立连接时RMI等待的时间。默认为15秒。
注:上述参数的值单位均为毫秒
影响垃圾回收的参数
java.rmi.dgc.leaseValue
此参数只影响服务端,它被用来设置标准的租赁时间。时间单位为毫秒,默认为10分钟。
sun.rmi.dgc.client.gcInterval
此参数用于配置客户端运行时行为。即RMI检测stub是否活动的时间周期。当stub不再被引用的时候,客户端运行时就会发送一个clean()消息给服务端运行时。单位为毫秒,默认为1分钟。
sun.rmi.dgc.server.gcInterval
服务端对于分布式垃圾回收的刷新频率。此参数用于控制检查客户端clean()的动作频率,并试图决定是否调用unreferenced()方法。此值单位为毫秒,缺省为1分钟。
sun.rmi.dgc.checkInterval
用于指定RMI检查过期租赁的频率。此值单位为毫秒,缺省为5分钟。
sun.rmi.dgc.cleanInterval
此参数是客户端的重试参数。当客户端调用clean()时,如果操作失败(如,网络问题),此参数将设定重新调用clean()时,客户端应该等待的时间。此值单位为毫秒,缺省为3分钟。
参考资料
1.O’Reilly <<Java RMI>> Chapter 16.The RMI Runtime
2.Java RMI 规范
1.它是序列化的,通过网络可以从服务端向客户端发送.也可以包含数据使其可以稳定地向服务端发送消息.
2.它是服务端的代理,客户端可以把stub当作是服务器.
3.它可以池化socket.每次方法调用的时候,stub就向RMI运行时请求一个特别服务的连接.这使得RMI可以在多个请求之间重用sockets(即可以共享socket).
在多个请求之间重用socket,可能会导致下面的问题:
如果一个socket被多个客户端的stubs重用,它们每一个都向不同的服务器发送了消息,那么这些消息之间应该有某种意义上的区别.那么应该如何来区分呢?
在RMI中,这种区分是通过使用java.rmi.server包下的ObjID类来进行的.
ObjID在javadoc中是这样定义的:
ObjID被唯一用来标识远程对象.每一个标识符都包含一个对象数(类型为long)和一个地址空间标识符(类型为UID,对于特定主机是唯一的).
对象标识符是在远程对象被导出时分配的.如果java.rmi.server.randomIDs属性设置为true的话,通过无参构造函数创建的ObjID对象的64位对象树将包含一个加密的强随机数.
因此,ObjID的实例可以唯一地标识服务器JVM中的特定服务.同时,ObjID类实现了序列化接口,因此,在每个远程方法调用时,其实例都可以被序列化.
在服务端,RMI运行时使用ObjID的反序列化来找出远程方法调用将要调用的skeleton.
RMI是怎样解决引导问题的?
大部分服务器在过去的使用中都是通过随机分配ObjID的实例来处理的.在其实例中有三种保留的标识符:ACTIVATOR_ID(),DGC_ID和REGISTRY_ID.
这三种IDs分别对应RMI提供的三种服务:激活构架,分布式垃圾收集和RMI注册表.
为了能够完全解决引导问题,RMI注册表需要预知的一个唯一标识符.
当一个客户端第一次试图连接RMI注册表的时候,除非它知道与服务器相关的对象标识符,否则此客户端就不能向服务器端发送消息.
也就是说,因为服务器端的RMI运行时需要一个ObjID的实例来决定使用哪个合适的服务器来响应客户端的请求,客户端为了能连接注册表,它必须要知道运行在服务器JVM中注册表的ObjID.
为了解决这个问题,RMI的设计者们定义了ObjID的保留实例-如果一个注册表运行在一个虚拟机中,它就使用REGISTRY_ID.否则,不允许任何服务器使用REGISTRY_ID.
这解决了RMI引导问题.Naming的静态方法接受一个主机和端口;构建stub时仅需的附加信息是stub连接服务器的Object ID.
由于注册表总是使用REGISTRY_ID,注册表的stub在连接注册表之前总是能在客户端被完全地构建.
这种策略也意味着,一个JVM只能导出一个注册表,这是因为不能在多个服务器间共享ObjID.
分布式垃圾收集
另一个固定的标识符是DGC_ID.这是内置于RMI中的关于分布式垃圾收集的对象标识符.
垃圾收集的基本想法是定义一系列的可到达对象,并丢弃那么不可达对象.可达对象是递归定义的:
1.每个活动线程当前都处在一个方法中或处在未知对象的实例中.那么线程所在的实例就是可到达的.
2.每个线程能够立即找到被方法级变量和实例字段引用的对象,这些对象也是可到达的.
3.从这些立即可访问的对象(此对象引用了其他对象),能够访问到其他可到达的对象.
诸如此类,一般来说,如果一个线程,从它当前位置开始,能够最终找到某个对象,那么此对象就是可达的.
在单个JVM中垃圾收集机制工作得很好.但在分布式系统中,stub问题将会出现.如果一个客户端拥有一个服务器端的引用 ,那么服务器应该是可到达的.
由于所有的stub真正拥有的是一个ObjId的实例,这意味着RMI运行时必须保持所有活动服务器的引用.为了垃圾回收,客户端的RMI运行时必须以某种方法让服务端运行时知道stub何时不再被使用.
最明显的方式是使用分布式引用计数.也就是,强制客户端stub发送两条额外的信息给服务器.
当stub被实例化发送一条消息,以便让服务器知道有一个活动的客户端(计数器加1).当stub释放的时候,再发送一条消息,以通知服务器客户端已经使用完了服务端(计数器减1).
在这种方案中,最脆弱的是第一步.下面的每一个问题都可能增加计数的困难度:
1.客户端垃圾收集算法不能保证立即回收stub.如果客户端的内存充裕,且正忙于处理具有高优先级的任务,那么垃圾收集暂时可能不会发生.在这段时期之内,客户端将隐含地强制服务端保持那些没有必要的资源.
2.客户端可能会崩溃(crash).假设一个客户端崩溃了的话,那么第二条消息将无法发送,这样就会导致服务端引用计数无法变为0,且RMI运行时将永远保持服务对象为活动状态.
3.可能会出现网络问题.即使客户端是好的,且能发送消息,但网络问题也可能出现.在这种情况下, RMI运行时决不将服务端引用减为0,这样就导致了服务端对象一直处于活动状态.
在这三个问题中,第一个问题是不可能解决的.Java语言规范明确的表明本地垃圾收集是不可依赖的.垃圾收集将来可能发生,但没有一种方式来强制它在某一时间段内发生.
在垃圾收集运行之前,没有一种方法知道一个stub变成了不可引用,因此任何一个分布式引用计数架构将不得不接受第一问题的现实.
第二和第三个问题可以通过将所有分布式引用作为临时引用来消除.其基本思想被称为租赁.基本算法如下:
1.客户端调用服务器并请求一段时间的租期.
2.服务端响应,并同意一段时间的租期(不一定与客户端请求的租期相同)
3.在这段时间之内,分布式引用计数将包含客户端(即增加计数1)
4.当租期期满的时候,如果客户端请求没有延长期限的话,则分布式应用计数将会自动减少(即减少计数1).
只要stub没有被垃圾回收的话,客户端就会自动尝试续期租赁.通过这种算法,可以灵巧地解决第二,第三个问题.
如果客户端崩溃了的话,即客户端就不再运行了,那么客户端就不能再续期租赁,结果就会导致服务器最终将其回收掉.
相似地,如果因网络问题阻止了客户端程序连接服务器,客户端也不会续期到租赁,因此服务端最终也会对其进行垃圾回收.
默认地租期为10分钟,可以通过java.rmi.dgc.leaseValue属性进行设置,时间单位为毫秒.
真实的分布式垃圾收集器
分布式垃圾收集器是一个RMI服务器程序,它实现java.rmi.dgc.DGC接口(此接口继承自java.rmi.Remote接口).此接口只包含两个方法声明:
public void clean(ObjID[] ids,long sequenceNum,VMID vmid,boolean strong)
public Lease dirty(ObjID[] ids,long sequenceNum,Lease lease)
clean()方法是由客户端在不需要服务端引用的时候,由它的运行时调用的.严格来讲,调用clean()方法是没有必要的-客户端运行时可能不续期租赁而达到相同的目的.
但是,租赁应该看作是服务器清理机制的最后一道防线(通过它可以在适当的位置减少网络和客户端失败造成的损害).
客户端运行时可以通过调用dirty()方法来获得一个租赁.不需要直接传递一个VMID(虚拟机ID,即一个JVM的唯一标识符)给dirty()方法,因Lease的实例已经传递了VMID(通过其构造函数可以看出).
注意:对于一个特定的JVM来说,它只能有一个分布式垃圾回收器,其对象标识符为DGC_ID.
Unreferecnced接口
分布式垃圾回收器负责维持租赁.在服务器端,当特定服务器的所有未解决租赁过期的时候,分布式垃圾回收器确保RMI运行时不再保留服务端引用.
因此服务端就可以被回收.在此处理过程中,如果服务端(远程对象)实现了Unreferenced接口,那么服务端在没有多个引用该对象的客户机时接收通知.Unreferenced接口只包含一个方法:
public void unreferenced()
当服务器需要立即释放资源而不是等待垃圾回收发生时,此接口非常重要.同时,它也是一个持久化代码的便利钩子-因为服务端知道不再有远程方法调用,所以它能将状态安全地存储到一个持久化介质(如,一个关系型数据库).
RMI日志
除了分布式垃圾回收之外,RMI运行时也包含广泛的日志,这些日志可以让你跟踪应用程序的行为.RMI中有三种不同的日志类型:标准日志,专门日志(包含5种类型),调试日志
标准日志
标准日志用于在服务端记录方法调用和异常信息.标准日志的使用是很容易的,可以通过设置java.rmi.server.logCalls系统属性(值为boolean类型)来启用或关闭.此属性可通过命令行或程序进行设置.如:
命令行:
Java -Djava.rmi.server.logCalls=true
程序:
System.getProperties().put("java.rmi.server.logCalls","true");
一旦你启用了日志,你可以配置日志的输出目的地.可以通使用java.rmi.server.RemoteServer类的静态方法进行设置:
public static PrintStream getLog()
用于获取当前的日志的流
public static void setLog(OutputStream out)
设置日志的输出流.
缺省情况下,日志系统使用System.err.也就是说,如果你没有设置标准日志输出目的地的话,它将会在System.err上显示.
专门日志
RMI有五种类型的专门日志用于记录运行时的特定方面.这些日志是transport log(传输日志),proxy log(代理日志),loader log(负载日志),DGC log(分布式垃圾回收日志)以及TCP log(tcp日志).
它们均为java.rmi.server.LogStream(此类从JDK1.3版本时已经被废弃)的实例.为了得到与日志相关的LogStream,可以调用其静态方法:public static LogStream log(String name).
一旦你有了LogStream的实例,就可以使用其 setOutputStream()来设置其输出目的地.如:
FileOutputStream transportLogFile = new FileOutputStream("d:/log/transportFlogFile"); LogStream.log("transport").setOutputStream(transportLogFile):
这些日志通过6个系统属性来操作,每一个属性都接受三个设置:silent(不记录信息),brief(记录少量信息),verbose(记录大量信息),可以使用s,b,v是上述三个值的简写形式.
此6个属性如下:(以下属性因为已被废弃,且属sun公司专有属性,具体含义可查看参考资料)
sun.rmi.server.dgcLevel
sun.rmi.server.logLevel
sun.rmi.loader.logLevel
sun.rmi.transport.logLevel
sun.rmi.transport.tcp.logLevel
sun.rmi.transport.proxy.logLevel
调试日志
同标准日志一样,可以通过设置系统属性sun.rmi.log.debug的boolean值来开启或禁用此功能.但不同于标准日志的是,调试日志总是将信息显示在System.err上.调试日志被用于激活框架的守护线程中.
基本RMI参数
java.rmi.server.randomIDS
其属性值为boolean型.当设置为true时,它强制RMI运行时为新导出的服务对象生成加密的安全对象标识.默认为false.
sun.rmi.server.exceptionTrace
其属性值为boolean型.当其设为true的时候(默认为false),所有的异常将会被打印到System.err上.反之,则不打印.
传输层参数
传输层是底层参数,它能够直接影响RMI底层的sokets的使用和TCP/IP的配置.有三个传输层参数:
sun.rmi.transport.connectionTimeout
用于设置在RMI关闭之前,socket的休眠时间.默认为15秒,在较慢的网络中,应该加大此值。
必须在客户端和服务器端同时设定此值,因为两端都试图重用同一个socket.如果服务端设为60秒的话,客户端设为15秒的话,那么实际上服务端设置的参数将会被客户端参数所否决。
sun.rmi.transport.tcp.readTimeout
设置底层socket读取超时时间,此参数的值实际上只能通过直接传递给socket的方式进行设值(通过socket的setSoTimeOut()).此参数的默认值为2个小时(7200,000毫秒)。
sun.rmi.transport.proxy.connectTimeout
用于设置在两个JVM建立连接时RMI等待的时间。默认为15秒。
注:上述参数的值单位均为毫秒
影响垃圾回收的参数
java.rmi.dgc.leaseValue
此参数只影响服务端,它被用来设置标准的租赁时间。时间单位为毫秒,默认为10分钟。
sun.rmi.dgc.client.gcInterval
此参数用于配置客户端运行时行为。即RMI检测stub是否活动的时间周期。当stub不再被引用的时候,客户端运行时就会发送一个clean()消息给服务端运行时。单位为毫秒,默认为1分钟。
sun.rmi.dgc.server.gcInterval
服务端对于分布式垃圾回收的刷新频率。此参数用于控制检查客户端clean()的动作频率,并试图决定是否调用unreferenced()方法。此值单位为毫秒,缺省为1分钟。
sun.rmi.dgc.checkInterval
用于指定RMI检查过期租赁的频率。此值单位为毫秒,缺省为5分钟。
sun.rmi.dgc.cleanInterval
此参数是客户端的重试参数。当客户端调用clean()时,如果操作失败(如,网络问题),此参数将设定重新调用clean()时,客户端应该等待的时间。此值单位为毫秒,缺省为3分钟。
参考资料
1.O’Reilly <<Java RMI>> Chapter 16.The RMI Runtime
2.Java RMI 规范
发表评论
-
RMI中的安全策略
2012-07-13 15:58 3458以下翻译来自Java RMI的Ch ... -
RMI动态类加载
2012-07-13 15:14 1461以下翻译自Java RMI的Chapter 19.Dynami ... -
RMI中的属性说明
2012-07-03 18:06 1324服务端属性 下面的表 ... -
O'reilly<<Java RMI>> 第18章:使用定制Socket (翻译)
2012-06-30 16:15 1454以下翻译来自:o'reilly ... -
RMI规范--第一章
2012-06-29 10:52 863原文网址: http://docs.or ... -
RMI规范--第十章
2012-06-29 10:50 717RMI 通信协议 10.1 概述 ... -
RMI规范--第九章
2012-06-29 10:29 771本章中的接口和类用于 ... -
RMI规范--第八章
2012-06-29 10:13 570本章包含 rmic stub 编译 ... -
RMI规范--第七章
2012-06-29 09:38 804远程对象激活 主题: 概述 激活协议 “可激活 ... -
RMI规范--第六章
2012-06-28 00:17 806注册服务程序接口 RMI 系统使用 java.rmi.re ... -
RMI规范--第五章
2012-06-28 00:16 833服务器接口 java.rmi.server 包包含通常用于 ... -
RMI规范--第四章
2012-06-28 00:15 794客户机接口 程序员在编写使用远程对象的 applet 或应 ... -
RMI规范--第三章
2012-06-28 00:14 769主题: Stub 与 skeleton ... -
RMI规范--第二章
2012-06-28 00:13 916Java 分布式对象模型 2.1 分布式对象应用程序 ... -
J2SE1.6 RMI官方指南翻译四
2012-06-27 18:20 971Compiling and Running the Examp ... -
J2SE1.6 RMI官方指南翻译三
2012-06-27 18:16 782Creating a Client Program The c ... -
J2SE1.6 RMI官方指南翻译二
2012-06-27 18:13 1064Implementing a Remote Interface ... -
J2SE1.6 RMI官方指南翻译一
2012-06-27 16:37 846最近在学习分布式 ... -
RMI 开发步骤
2012-06-25 18:36 1313开发RMI步骤: 1.编写服务接口,此接口须直接或间接继承至R ... -
JDK1.6 rmic命令使用
2012-06-25 18:24 1397rmic称为rmi编译命令,用于生成rmi远程实现类的stub ...
相关推荐
有很多关于rmi的调用说明,在最后的运行时总是不太详细,通过多方查阅,写了一段代码,供大家参考,希望对大家有帮助。
java rmi 完整的简单例子 包含详细的文档说明
RMI的一个完整demo,有文件,说明,可以直接运行看到效果 对于初学者很有用,呵呵,完全免费的啦
讲述 RMI 是什么,作用是什么,运行原理,主要用到的函数等。
编译和运行项目的说明 克隆文件或下载.zip; 打开rmi-project / src目录; 使用cmd使用以下代码检查计算机的ip: ipconfig ; 在类StartClient.java和StartServer.java更改ip; 使用cmd或git bash,使用以下命令...
如果未提供端口,它将在默认端口1099上运行: rmiregistry 编译BankServerImpl.java文件javac BankServerImpl.java编译BankClient.java文件javac BankClient.java运行BankServerImpl并在端口RMI运行时提供输入。...
网络使用Java RMI for RPC实现类似Chord的逻辑。 Maven用于构建运行项目所需的胖JAR。 该项目包含两个需要构建的JAR,分别是BootStrapNode JAR和ChordNode JAR,可以通过将pom.xml(第24行)中的MainClass更改为...
当然也可以在Eclipse中配置运行时程序的参数来运行程序(运行时参数主要负责传递端口号,服务器地址等)。 Ch12:基于Agent实现的分布式计算 本程序的运行基于Aglet,首先要安装和配置Aglet:推荐安装Aglet稳定...
启动窗口和结束窗口启动窗口是启动自动运行菜单时显示的窗口,而结束窗口则是退出菜单时显示的窗口。可以在启动窗口和结束窗口中使用不规则外观以及淡入淡出特效。测试按钮可以测试启动窗口和结束窗口的实际效果。...
启动窗口和结束窗口启动窗口是启动自动运行菜单时显示的窗口,而结束窗口则是退出菜单时显示的窗口。可以在启动窗口和结束窗口中使用不规则外观以及淡入淡出特效。测试按钮可以测试启动窗口和结束窗口的实际效果。...
rmi 轻松部署简单聊天客户端 - 服务器的 Java 应用程序##版本服务器-客户端:简单的服务器-客户端聊天 irc 风格,用于客户端之间的普通聊天P2P:点对点版本,带服务器同步联系人,允许基于“IRC”的聊天和一对一聊天...
29 3.2.2 Class.forName()加载类的实例 30 3.2.3 loadClass获得类的实例 31 3.3 操作类的字段 31 3.3.1 获取对象的属性 31 3.4 操作类的方法 34 3.4.1 运行时调用对象的方法 34 3.4.2 无参构造函数 36 3.4.3 带参...
2、修正了设置为 自动开机运行 时有时不能正确自动运行的问题; 3、增加了一个About窗口(做广告?); 4、重写了播放器代码,现在可以支持更多的格式:wav,wma,mid,rmi,mp3……等。如果在你的机器上出现某种声音...
它是使用RMI用Java编写的。 运行简单测试 简单测试说明: 4个服务器实例一直在运行 使用GET方法运行1个客户端(下载文件) 使用PUT方法运行1个客户端(上传文件) 使用PUT方法运行1个客户端(上传现有文件-用较...
java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法...
介绍利用java程序检查服务器或主机的运行时信息,包括操作系统、CPU使用情况、内存使用情况、硬盘使用情况以及网卡、网络信息。主要的办法有两 种:第一种,使用jdk1.6以上自动的功能,实现数据的获取,但是该方法...
2.RMI服务(RIM远程唤出),绑定服务的端口号,“rmi.port=值”, 如果不配置或配置错误则在 1100-9999 这个范围内使用一个可用的端口, 如果最终无可用端口则抛出异常,继续运行工具,但无法远程唤出工具。
运行说明: 将 ds.war 放到 Apache webapps 目录中 通过执行以下命令启动 RMI 服务: java -cp crypto.jar ie.gmit.FibService 从带有 crypto.jar 的文件夹中 将浏览器指向 主要特点: RMI 服务计算斐波那契数 ...
java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 6、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法...
内容提要:配置、创建并运行 Quartz RMI 端户端,演示了 Quartz RMI 客户端通过远程调度器部署一个 Job 的 的例子。 第十章. J2EE 中使用 Quartz (第一部分) 内容提要:J2EE 中引入 Quartz。在 J2EE 环境中作为 ...