java.net.SocketTimeoutException: Read timed out

8
我有一个客户端服务器架构的应用程序。客户端使用Java Web Start和Java Swing / AWT,而服务端使用HTTP服务器/Servlet和Tomcat。
通信是通过对象序列化实现的,创建ObjectOutput序列化字节数组并发送到服务器,分别调用ObjectInputStream进行反序列化。
该应用程序在某个并发时间内正确通信,但随着时间的推移,开始显示错误“SocketException read timeout”。当服务器在我的servlet doPost方法中调用ObjectInputStream.getObject()方法时,发生了错误。
Tomcat会变慢,并且错误会导致服务器响应时间减少,直到崩溃时我必须重新启动服务器,然后一切正常。
有人遇到过这个问题吗?
客户端代码
URLConnection conn =  url.openConnection();
conn.setDoOutput(true);

OutputStream os = conn.getOutputStream();
ObjectOutputStream oss = new ObjectOutputStream(os);

oss.writeUTF("protocol header sample");

oss.writeObject(_parameters);
oss.flush();
oss.close();

服务器代码

ObjectInputStream input = new ObjectInputStream(_request.getInputStream());
String method = input.readUTF();

parameters = input.readObject();

input.readObject() 是出现错误的地方。


SocketException 异常发生前经过的时间是 20 分钟或更长吗?(如果我记得没有连接活动时 TCP/IP 套接字超时等待的标准时间)?毕竟,异常告诉你“读取超时”,这可能与 Web 的异步性有关吗? - Wintermut3
这是一个TCP Linux参数吗?例如缓冲区大小、最大打开文件数或其他参数? - Rafael Soto
2个回答

10

您提供的信息不够详细,特别是关于客户端方面。但我怀疑客户端出现了以下问题:

  • 未能设置Content-length头部(或将其设置为错误的值)
  • 未能刷新输出流,和/或
  • 没有关闭套接字的输出端。

很神秘。

根据您更新的问题,似乎以上都不是问题。还有其他几种可能性:

  • 由于序列化时客户端要么完全锁定,要么花费非常长的时间。
  • 客户端和服务器之间存在一个代理,导致问题。
  • 您遇到了与负载相关的网络问题或网络硬件问题。

另一个可能的解释是您存在内存泄漏,并且当内存耗尽时,GC需要更多的时间,从而导致减速。如果您启用了GC日志,这将显示在日志中。


0

我认为在高并发情况下,Tomcat中设置的Socket超时时间已经过期并且连接已关闭。Tomcat对该连接的下一次读取大于服务器套接字超时时间。
如果您想避免这个问题,您必须增加服务器端的超时时间,这在您的情况下已经过期。但不建议这样做。
顺便说一句,您没有提供足够的信息。您是否增加了Tomcat连接线程数?如果是,那么这肯定会发生。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接