Java WebService客户端部署Windows机器连接超时问题求助
排查思路:Java WebService客户端连接超时但SOAPUI正常
这种场景我之前帮客户排查过好多次,核心矛盾点很明确——SOAPUI能正常调用但Java客户端超时,说明网络链路本身是通的,问题出在Java客户端和SOAPUI的配置差异,或者安全软件对Java进程的限制上。结合你提供的日志(核心是java.net.ConnectException: Connection timed out),给你一步步的排查思路:
1. 优先检查代理配置差异
SOAPUI通常会自动读取Windows系统代理(比如IE的代理设置),但Java默认不会自动继承系统代理,这是最常见的原因:
- 临时在Java启动参数中添加代理配置测试:
如果代理需要身份认证,补充:-Dhttp.proxyHost=你的代理IP -Dhttp.proxyPort=代理端口 -Dhttps.proxyHost=你的代理IP -Dhttps.proxyPort=代理端口-Dhttp.proxyUser=用户名 -Dhttp.proxyPassword=密码 -Dhttps.proxyUser=用户名 -Dhttps.proxyPassword=密码 - 也可以通过CXF代码直接配置代理(更灵活):
Client client = ClientProxy.getClient(yourWebServicePortInstance); HTTPConduit conduit = (HTTPConduit) client.getConduit(); ProxyAuthorizationPolicy proxyAuth = conduit.getProxyAuthorizationPolicy(); proxyAuth.setProxyServer("代理IP"); proxyAuth.setProxyServerPort(代理端口); proxyAuth.setUserName("代理用户名"); proxyAuth.setPassword("代理密码");
2. 检查安全软件的进程拦截规则
客户机器上的Forescout、卡巴斯基很可能拦截了Java进程的出站请求,但放过了SOAPUI:
- 打开卡巴斯基的应用控制模块,确认你的Java程序(比如
java.exe或者你的Jar包进程)是否被禁止访问外部网络,将其加入白名单。 - 检查Forescout的网络策略,它会对进程的流量做细粒度控制,需要确保你的Java进程被允许访问目标WebService的端口(通常是443/80)。
- 如果客户允许,临时关闭安全软件测试,快速验证是否是安全软件导致的拦截。
3. 确认信任库配置是否实际生效
你本地配置了cacerts,但部署到客户机器后,Java可能没有使用你自定义的信任库,而是默认JRE的cacerts:
- 启动Java程序时明确指定信任库参数:
-Djavax.net.ssl.trustStore=你的信任库文件路径 -Djavax.net.ssl.trustStorePassword=信任库密码 - 检查客户机器上的JRE版本,确保和你本地一致,避免因JRE版本不同导致信任库路径或证书兼容性问题。
4. 排除CXF框架的网络协议/超时配置问题
CXF客户端可能默认禁用了某些TLS版本,或者超时设置过短:
- 强制Java使用TLSv1.2(很多WebService现在只支持这个版本):
System.setProperty("https.protocols", "TLSv1.2"); - 检查CXF的超时设置,适当调大避免超时:
Client client = ClientProxy.getClient(yourWebServicePortInstance); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); policy.setConnectionTimeout(30000); // 30秒连接超时 policy.setReceiveTimeout(60000); // 60秒接收超时 conduit.setClient(policy);
5. 补充:忽略Ping失败的干扰
Ping失败完全不代表HTTP/HTTPS链路不通——很多服务器会禁用ICMP响应,SOAPUI能正常调用已经证明应用层是可达的,不用在Ping上浪费时间。
附:你提供的错误日志
2020-08-30 13:18:27 DEBUG (PhaseInterceptorChain.java:305) - 调用拦截器org.apache.cxf.ws.policy.PolicyVerificationOutInterceptor@61884cb1上的handleMessage方法 2020-08-30 13:18:27 DEBUG (PolicyVerificationOutInterceptor.java:78) - 已验证出站消息的策略。 2020-08-30 13:18:27 DEBUG (PhaseInterceptorChain.java:305) - 调用拦截器org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor@423e4cbb上的handleMessage方法 2020-08-30 13:18:27 DEBUG (PhaseInterceptorChain.java:305) - 调用拦截器org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor@545de5a4上的handleMessage方法 2020-08-30 13:18:27 DEBUG (PhaseInterceptorChain.java:305) - 调用拦截器org.apache.cxf.interceptor.StaxOutEndingInterceptor@acb0951上的handleMessage方法 2020-08-30 13:18:27 DEBUG (PhaseInterceptorChain.java:305) - 调用拦截器org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@1d7f7be7上的handleMessage方法 2020-08-30 13:18:27 DEBUG (Headers.java:320) - Accept: */* 2020-08-30 13:18:27 DEBUG (Headers.java:320) - Authorization: *** 2020-08-30 13:18:27 DEBUG (Headers.java:320) - Connection: Keep-Alive 2020-08-30 13:18:27 DEBUG (HTTPConduit.java:1814) - 管道'{xxx}'无信任决策器,默认采用信任决策。 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@1d7f7be7上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.interceptor.StaxOutEndingInterceptor@acb0951上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor@545de5a4上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor$SoapOutEndingInterceptor@423e4cbb上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.ws.policy.PolicyVerificationOutInterceptor@61884cb1上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal@3faf2e7d上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.binding.soap.interceptor.RPCOutInterceptor@3cfdd820上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor@e25951c上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor@2e11485上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.interceptor.StaxOutInterceptor@6b0d80ed上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JStaxOutInterceptor@60dce7ea上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.interceptor.AttachmentOutInterceptor@452e19ca上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.interceptor.MessageSenderInterceptor@64ec96c6上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor@928763c上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.ws.security.policy.interceptors.SecurityVerificationOutInterceptor@fd8294b上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.binding.soap.interceptor.SoapHeaderOutFilterInterceptor@6f8e8894上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor@456d6c1e上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.jaxws.interceptors.SwAOutInterceptor@77659b30上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.jaxws.interceptors.HolderOutInterceptor@1e13529a上的handleFault方法 2020-08-30 13:18:48 DEBUG (PhaseInterceptorChain.java:496) - 调用拦截器org.apache.cxf.ws.policy.PolicyOutInterceptor@1b410b60上的handleFault方法 2020-08-30 13:18:48 WARN (LogUtils.java:475) - {xxx}的拦截器抛出异常,正在回滚 org.apache.cxf.interceptor.Fault: Could not send Message. at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:67) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140) at com.sun.proxy.$Proxy35.deleteBook(Unknown Source) at it.main.MyMain.main(MyMain.java:65) Caused by: java.net.ConnectException: ConnectException invoking xxx: Connection timed out: connect at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1400) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1384) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:671) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) ... 9 more Caused by: java.net.ConnectException: Connection timed out: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source) at sun.net.www.protocol.https.HttpsClient.New(Unknown Source) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source) at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:274) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1343) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1304) at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:307) at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47) at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1356) ... 12 more
内容的提问来源于stack exchange,提问作者Frank




