我有一个Apache CXF 2.7.8使用者调用另一个SOAP Web服务.
在我的开发环境(Tomcat 6.0,jdk1.7.0_51,Windows 7)中,一切都很迷人.
然而;当我将代码部署到测试环境(WebLogic 12.1,jdk1.7.0_51,RHEL 6)时,我得到一个javax.xml.ws.WebServiceException:无法发送由java.net.SocketTimeoutException引起的Message异常:读取超时在每秒请求x毫秒之后.
开发和测试实例都调用完全相同的服务器.
当我执行网络跟踪时,我看到CXF使用相同的套接字连接发送了许多请求(感谢HTTP Keep-Alive).最终,服务器发送一个FIN,指示客户端应该停止使用此连接(如果需要,建立一个新连接).客户端确认FIN,但随后继续在同一套接字上发送下一个请求,尽管已被告知断开连接(并确认该指令).然后服务器发送一个RST(如预期的那样),告诉客户端消失.然后客户端再次尝试.最终,我们达到Read超时已经过了足够的时间,并且抛出了上面的SocketTimeoutException.
(顺便说一句:在Windows开发平台上,客户端尊重FIN并为下一个请求建立新的套接字连接).
当我禁用HTTP Keep-Alive(使用指令here)时,服务器仅在客户端发送一个请求后发送FIN(完全如此).客户端仍然使用该帧的ACK确认FIN,然后大胆地继续尝试使用该套接字.
我很乐意让HTTP Keep-Alive工作,但是如果没有它,我会满足于工作.
有任何建议的解决方案或后续步骤进行故障排除吗
解决方法:
以下是我们迄今为止所学到的内容,希望能够帮助其他人:
>在Oracle JRE 1.7.0_51-b13中,当用户java.net.HttpURLConnection和javax.net.ssl.HttpsURLConnection(两个java.net.URLConnection的子类)启用HTTP KeepAlive时,服务器终止HTTP连接(如它允许按照RFC),JRE不适当地继续使用断开连接的套接字(当该套接字处于看似FIN_WAIT状态之一时).这样做时,JRE在套接字发送上“等待”(永远不会返回响应),直到读取超时发生时,抛出套接字超时异常.此功能在WebSphere下的IBM JRE中正常工作,但在WebLogic下的Oracle JRE中不能正常工作.
>在同一个Oracle JRE版本中,当HTTP或HTTPS请求中的“Connection:”头字段设置为“close”(而不是Keep-Alive)时,根据RFC,URLConnection的子类继续尝试重用它底层套接字,即使它们不应该.
我们的解决方法是将“http.keepAlive”系统属性设置为“false”以禁用所有连接上的保持活动状态.这不是一个可接受的长期解决方法,因为在每个请求上设置和分解连接所需的额外时间和资源开销是不可接受的 – 我们必须继续努力才能使其正常工作.