Java RMI 调用无故失败几百次

Java RMI calls fail for no reason once in a few hundred

我编写了测试 RMI 服务器和客户端程序。在服务端有一种方法暴露给客户端。

在客户端,我使用 600 线程的执行器服务调用 RMI 方法 6000 次。

在服务器上,每个方法调用都会创建一个简单的任务并将其提交给一个 300 线程的执行器服务。

每次执行我只得到一两次异常。因此,对于 6000 次调用,我得到大约 1 到 3 个异常。此外,这些异常似乎只发生在初始启动期间。

java.rmi.ConnectIOException: Exception creating connection to: ; nested exception is: 
java.net.SocketException: Connection reset by peer
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:129)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy0.receiveMessage(Unknown Source)
at com.example.rmi.MsgTask.run(MsgTask.java:18)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

客户端和服务器 运行 在同一台机器上,相同的 Eclipse IDE。

看起来如果 rmi 服务器程序在收到请求时忙了几毫秒,请求可能会被丢弃。这个可以吗?我是否应该将此行为视为正常行为并在将来在我的 RMI 客户端中构建 'retry' 方法?或者,我可以更改一些设置以确保不会丢弃请求吗?

错误处理总是一个好主意,尤其是在网络调用中。不管你是否真的有问题。所以是的,我会处理这个并提供重试。

顺便说一下,600 个线程对我来说似乎有点太多了。减少它们可能会解决您的问题。

您 运行 进入 TCP 侦听积压。当它填满时,Windows 主机将发出 'connection reset'.

解决方案是减少您的负载或引入重试,在一个小但增加的睡眠间隔之后。