【问题标题】:Java RMI calls fail for no reason once in a few hundredJava RMI 调用数百次无缘无故失败
【发布时间】:2016-02-04 13:59:15
【问题描述】:

我编写了测试 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 客户端中构建“重试”方法?或者,我可以更改一些设置以确保请求不会被丢弃吗?

【问题讨论】:

  • 看起来在 RMI 服务器端对象中收到的每个调用都在一个单独的线程上。因此,无需在服务器端使用手动线程。虽然,如果留给“自动”,线程数似乎没有上限。
  • 没那么简单。 RMI 规范在这一点上故意模糊不清,但您可以从它所说的内容中得到一件事,即您不能假设 RMI 服务器是单线程的。您在 Sun/Oracle JDK 中真正得到的是每个连接一个线程。

标签: java multithreading rmi


【解决方案1】:

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

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

【讨论】:

  • 我同意他应该尝试减少线程数。 500个线程是否仍然存在问题? 100? 10 点?
【解决方案2】:

您遇到了 TCP 侦听积压。当它填满时,Windows 主机将发出“连接重置”。

解决方案是在一小段但不断增加的睡眠间隔后减少负载或引入重试。

【讨论】:

  • 非常感谢您指出这个方向。我在 MacBook Pro 上运行它。希望你的回答仍然适用。关于可能失败的积压 KB 的任何粗略数字......
  • 积压计入连接数。它与千字节没有任何关系。它可以是 5 到 500 或更多之间的任何值,如果不深入内核,就无法发现它的实际含义。
  • 就像你提到的那样......我在谷歌上搜索了“TCP 侦听积压”并找到了stackoverflow.com/questions/114874/…tangentsoft.net/wskfaq/advanced.html#backlog
猜你喜欢
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多