RMI的一个比较棘手的问题

junnef 2005-10-25 03:39:36
有一个RMI远程对象,在RMI中注册后,有多用户在同一时段内访问该服务。
要求是RMI服务端需要记录每一个访问用户的一些状态信息,在用户发了一个新的请求时,要求能够把每一个用户的状态信息明确区分出来,并返回一些状态信息给用户,类似于有状态的session bean。
当前采用的实现方法是用一个HashMap对象和一个自定义的数据model来实现,key为用户id,用户相关信息为model实例,可以实现基本要求。但是对于用户状态的管理比较复杂,需要自己实现对长时间无动作的用户状态信息进行清理,还有并发问题可能也是一个瓶颈。
现在的问题是有没有更好的在RMI服务段保持用户状态的解决方法?

先说几种没有折中的情况:
1、必须RMI服务端保存用户的一些信息。
2、已经明白问题的实质在于多用户都是请求的同一个RMI服务端对象实例,这个实例中的属性也为大家共用,所以,一个用户的更改动作就会让其他用户也得到更该后的结果,如果有办法可以对不同的用户创建不同的服务对象实例,但是都是同一个服务注册名称,这样就不用自己维护HashMap中的状态了,每一个用户的状态可以维护在自己的对象实例中,直到用户断开连接该实例不再有引用被回收站回收为止。
...全文
421 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
junnef 2006-03-15
  • 打赏
  • 举报
回复
自己早搞定了,揭帖。
junnef 2005-11-23
  • 打赏
  • 举报
回复
我是在本级调试,所以不存在java虚拟机的安全权限和防火墙问题,这个可以排除,而且我的机器没有装防火墙;是注册激活对象的,但是事实就是服务器的connectiontimeout属性设置为15秒,如果15秒内没有任何一个连接发送动作请求,则所有的连接都将被销毁,然后再去连接这个服务时,不论哪一个都无法连接上,提示请求超时,其实就是该服务的监听没有了,但不影响在同一个rmiregistry中注册其他服务;如果单独开一个客户端,每隔15秒发送一个简单的请求,然后再用其他的客户端去连接,不管其他客户端间隔多长时间都可以顺利连接上去。查了一下资料,据说是rmiregistry本身实现有问题,不敢确定。
gemouzhi 2005-11-21
  • 打赏
  • 举报
回复
关于你说的Timeout我建议你调试程序的时候把防火墙关掉
gemouzhi 2005-11-21
  • 打赏
  • 举报
回复
服务监听就被销毁了?

不会的,你是注册激活的对象吧。
junnef 2005-11-21
  • 打赏
  • 举报
回复
好像是rmiregister的本身机制有点问题,我单独先开一个客户端,每一秒钟都请求一次RMI服务,这个服务很简单,就是请求一个字符串,让它一直保持连接。然后我开始做的那个通过sessionbean客户端请求就可以反复很顺利的请求到了,具体原因没搞清楚,我估计是当客户端在一段时间内没有请求,服务监听就被销毁了,然后再请求就没反应了。谁知道具体原因?
Mybeautiful 2005-11-17
  • 打赏
  • 举报
回复
给大哥up一下
notruiyi 2005-11-17
  • 打赏
  • 举报
回复
你是在做EJB服务器吗?你的问题没碰到过,会不会是绑定错误,建议还是自己启动一个WEB服务来负责传输对象,rmiregister经常有问题
junnef 2005-11-16
  • 打赏
  • 举报
回复
还有一个很基本的问题,RMI我启动了一个服务,如果有多人同时请求,RMI是不是也是多线程的模式来响应的?我的服务类没有实现线程.
junnef 2005-11-16
  • 打赏
  • 举报
回复
这个东西自己实现了以后,发现老是出现
10:51:21,406 INFO [STDOUT] java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketTimeoutException: Read timed out
10:51:21,406 INFO [STDOUT] at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:274)
10:51:21,406 INFO [STDOUT] at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
10:51:21,406 INFO [STDOUT] at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)
10:51:21,406 INFO [STDOUT] at com.aeroinfo.rmi.control.TransferObject_Stub.openCube(Unknown Source)
10:51:21,406 INFO [STDOUT] at com.aeroinfo.business.session.BusinessLogicSessionBean.OLAP_OpenCube(BusinessLogicSessionBean.java:8169)
连接超时异常,查资料也没什么结果,谁知道怎么回事?谢谢.
junnef 2005-11-16
  • 打赏
  • 举报
回复
自己顶,没人知道rmi为什么超时么?
notruiyi 2005-10-26
  • 打赏
  • 举报
回复
不过在rmiregister,有更好的解决办法,就是自己启动一个 web服务器,最小型的那种,他们可以负责对象传输
notruiyi 2005-10-26
  • 打赏
  • 举报
回复
基本同意楼主的想法,ejb是垃圾,自己做分布式更放心
junnef 2005-10-26
  • 打赏
  • 举报
回复
回复人: cjhyahoo(野虎) ( ) 信誉:89
实例化多个RMI服务对象,每个注册一个服务名,
不同用户访问不同RMI服务名,
每个服务中的方法同步,
这样看看

这个设计方案更复杂了,要多起一个RMI服务来创建这些实例,然后把新创建的实例名称返回给客户端,客户端来访问新创建的实例,同时还要做好实例的回收工作,否则越开越多,又要设计一个实例池,不如通过直接访问一个RMI服务实例,然后,每来一个用户都要先调用一个方法来创建属于自己的信息对象,并记录到一个HashMap对象中去,每次用户请求动作时,都要传入自己的ID,通过ID去HashMap中查找属于自己的实例对象,每个用户的数据状态也记录在其中。只需要开个线程去维护这个HashMap就行了,做一个类似session中对象的实效机制,超时就可以把它remove掉。

现在写好了一个用户状态管理类,开了一个线程专门维护已经存储在HashMap中的用户状态model对象,性能感觉还可以。先凑合用吧,现在最主要的是想找一个可以运行在jvm中自己管理不同请求的用户的信息状态的方法,就像有状态的会话bean一样,可以由容器管理,每个客户端只需要记住自己的sessionid就可以了。
cjhyahoo 2005-10-25
  • 打赏
  • 举报
回复
实例化多个RMI服务对象,每个注册一个服务名,
不同用户访问不同RMI服务名,
每个服务中的方法同步,
这样看看
junnef 2005-10-25
  • 打赏
  • 举报
回复
自己写了一个RMI的服务起动类,带main方法的可以自己运行的,运行rmiregister,然后运行这个类就可以启动RMI服务了。用RMI就是不想再做一个中间件的服务器了,实在没有其他的解决办法,就自己开始开一个线程维护用户状态信息了,只要用户状态的维护不影响主服务就行了。至于RMI服务交给JVM管理去吧。
notruiyi 2005-10-25
  • 打赏
  • 举报
回复
估计不行,其实不管什么服务器都有主线程和子线程,你要全部并行估计不行,
在这种事务服务器中这中情况应该很常见,你是打算怎么实现java服务器吗?jboss?
不然干脆使用ejb有状态会话bean

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧