java rmi 感知断开_java – 什么可能导致RMI方法调用间歇性失败?

长话短说,我有一个RMI服务器和客户端.服务器和客户端能够相互进行RMI调用.客户端连接到服务器后,服务器可以在客户端上快速连续进行数百个方法调用.

问题是这样 – 在大量的服务器到客户端方法调用结束时,有些会失败,因为RMI声称它无法建立从服务器到客户端的连接,即使它之前的数百个调用都会成功.我不能发布任何真正的代码,因为这个项目相当大(约50k行),但这里是抛出异常的完整堆栈跟踪:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:

java.net.SocketException: Connection reset

at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)

at sun.rmi.transport.Transport$1.run(Unknown Source)

at java.security.AccessController.doPrivileged(Native Method)

at sun.rmi.transport.Transport.serviceCall(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)

at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)

at sun.rmi.server.UnicastRef.invoke(Unknown Source)

at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)

at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)

at $Proxy0.findClassDefinition(Unknown Source)

at com.fabric.network.NetworkClassLoader.findClass(NetworkClassLoader.java:111)

at java.lang.ClassLoader.loadClass(Unknown Source)

at com.fabric.network.NetworkClassLoader.loadClass(NetworkClassLoader.java:131)

at java.lang.ClassLoader.loadClass(Unknown Source)

at com.fabric.network.MessageSocket$CustomObjectInputStream.resolveClass(MessageSocket.java:171)

at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)

at java.io.ObjectInputStream.readClassDesc(Unknown Source)

at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)

at java.io.ObjectInputStream.readObject0(Unknown Source)

at java.io.ObjectInputStream.defaultReadFields(Unknown Source)

at java.io.ObjectInputStream.readSerialData(Unknown Source)

at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)

at java.io.ObjectInputStream.readObject0(Unknown Source)

at java.io.ObjectInputStream.defaultReadFields(Unknown Source)

at java.io.ObjectInputStream.readSerialData(Unknown Source)

at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)

at java.io.ObjectInputStream.readObject0(Unknown Source)

at java.io.ObjectInputStream.readObject(Unknown Source)

at com.fabric.network.MessageSocket.receive(MessageSocket.java:118)

at com.fabric.application.driver.NodeRemoteDriver$IncomingMessageThread.run(NodeRemoteDriver.java:205)

Caused by: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:

java.net.SocketException: Connection reset

at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)

at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)

at sun.rmi.server.UnicastRef.invoke(Unknown Source)

at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)

at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)

at $Proxy2.findClassDefinition(Unknown Source)

at com.fabric.network.ClassDefinitionCache.findClassDefinition(ClassDefinitionCache.java:78)

at com.fabric.management.host.NodeManagementServices.findClassDefinition(NodeManagementServices.java:231)

at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)

at sun.rmi.transport.Transport$1.run(Unknown Source)

at java.security.AccessController.doPrivileged(Native Method)

at sun.rmi.transport.Transport.serviceCall(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

Caused by: java.net.SocketException: Connection reset

at java.net.SocketInputStream.read(Unknown Source)

at java.io.BufferedInputStream.fill(Unknown Source)

at java.io.BufferedInputStream.read(Unknown Source)

at java.io.DataInputStream.readByte(Unknown Source)

... 21 more

再说一遍,抱歉,我不能提供很多代码方式,但我不一定要求修复代码 – 我只是想了解为什么会发生这种情况.

编辑

添加了完整的堆栈跟踪.

解决方法:

好吧,所以几乎把我所有的头发拉出来之后,事实证明RMI正试图打开太多的端口.我正在使用自定义的RMISocketFactory实现.这个自定义实现是一个单例,所以我认为没有必要实现hashCode()和equals().确实是一个非常痛苦的错误……

事实证明,如果RMI确定它需要创建的套接字是由RMISocketFactory创建的,那么RMI将不会重用套接字,该RMISocketFactory不等同于创建它想要重用的套接字的工厂. RMI依赖equals()和hashCode()来执行此检查.一旦我在自定义套接字工厂中正确实现了这两种方法,这些间歇性问题就消失了.

可以在此处找到此问题的描述:

无论如何,感谢大家一起来看看这个,我当然感谢您的光临!

附加信息

我之前没有注意到的第二个问题是我使用的ServerSocket用完了传入连接请求的队列空间,这也导致连接被丢弃.使用构造函数新的ServerSocket(port,newConnectionQueueSize,bindAddress)和更大的newConnectionQueueSize也有助于解决此问题.

标签:java,networking,rmi

来源: https://codeday.me/bug/20190826/1729356.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值