最近遇到一个比较棘手的问题:
问题是这样的,搭建了一个webservice的服务平台,让后提供给多个接口调用,有两家接口调用了同样的一个方法,但是第一家的接口从来没有出现过问题,而另一家就奇怪了,最近总是出现 socket通信中断的情况,客户端报错如下:
调用WebService时找不到方法:doDownloadRecipeInfo。原因:System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: 远程主机强迫关闭了一个现有的连接。. ---> System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接。
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at EnterpriseServerBase.WebService.DynamicWebCalling.HdyyElectronicService.doDownloadRecipeInfo(String userName, String password, String senderCode)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at XmlTrans.Core.WSHelperCore.InvokeWebServiceMethod(String methodname, Object[] args)
而在服务端报错为:
2018-03-27 10:09:35,996-135315 ERROR [org.apache.axis2.transport.http.CommonsHTTPTransportSender] (http-apr-8082-exec-1:)
org.apache.axis2.AxisFault
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:78)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.sendUsingOutputStream(CommonsHTTPTransportSender.java:364)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:241)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:43)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2442)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2431)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.ctc.wstx.exc.WstxIOException: null
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1692)
at com.ctc.wstx.sw.BaseStreamWriter.close(BaseStreamWriter.java:288)
at org.apache.axiom.util.stax.wrapper.XMLStreamWriterWrapper.close(XMLStreamWriterWrapper.java:46)
at org.apache.axiom.om.impl.MTOMXMLStreamWriter.close(MTOMXMLStreamWriter.java:222)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:192)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:74)
... 28 more
Caused by: ClientAbortException: java.io.IOException
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:413)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:359)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:333)
at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:101)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:124)
at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:99)
at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:214)
at com.ctc.wstx.sw.BufferingXmlWriter.close(BufferingXmlWriter.java:194)
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1690)
... 33 more
Caused by: java.io.IOException
at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:205)
at org.apache.coyote.http11.InternalAprOutputBuffer.access$100(InternalAprOutputBuffer.java:37)
at org.apache.coyote.http11.InternalAprOutputBuffer$SocketOutputBuffer.doWrite(InternalAprOutputBuffer.java:235)
at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:93)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:520)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:408)
... 42 more
2018-03-27 10:09:35,998-135317 ERROR [org.apache.axis2.transport.http.CommonsHTTPTransportSender] (http-apr-8082-exec-1:)
org.apache.axis2.AxisFault
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:78)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.sendUsingOutputStream(CommonsHTTPTransportSender.java:364)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:241)
at org.apache.axis2.engine.AxisEngine.sendFault(AxisEngine.java:526)
at org.apache.axis2.transport.http.AxisServlet.handleFault(AxisServlet.java:433)
at org.apache.axis2.transport.http.AxisServlet.processAxisFault(AxisServlet.java:398)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:188)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2442)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2431)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.ctc.wstx.exc.WstxIOException: null
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1692)
at com.ctc.wstx.sw.BaseStreamWriter.close(BaseStreamWriter.java:288)
at org.apache.axiom.util.stax.wrapper.XMLStreamWriterWrapper.close(XMLStreamWriterWrapper.java:46)
at org.apache.axiom.om.impl.MTOMXMLStreamWriter.close(MTOMXMLStreamWriter.java:222)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.serializeAndConsume(OMSerializableImpl.java:192)
at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:74)
... 26 more
Caused by: ClientAbortException: java.io.IOException
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:413)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:359)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:333)
at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:101)
at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:99)
at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:214)
at com.ctc.wstx.sw.BufferingXmlWriter.close(BufferingXmlWriter.java:194)
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1690)
... 31 more
Caused by: java.io.IOException
at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:205)
at org.apache.coyote.http11.InternalAprOutputBuffer.access$100(InternalAprOutputBuffer.java:37)
at org.apache.coyote.http11.InternalAprOutputBuffer$SocketOutputBuffer.doWrite(InternalAprOutputBuffer.java:235)
at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:93)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:520)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:408)
... 39 more
更具客户端和服务端的报错,知道是Socket IO异常造成的,但是好好的用着为什么就出现了IO读写异常了呢?平常也都是这样用的呀!
带着满脸的疑问,开始寻找问题所在吧。
首先,就是在网上找各种解决办法,网上说法很多,最早是以为webservice的方法没有成功调通就被关掉了,后来经过测试,证明服务是能够被成功调通的,只是webservice方法返回给客户端返回值的时候出现异常,导致socket通信中断。那为什么返回数据的时候会导致通信连接被断掉呢?在网上搜答案,网上各种说法都有,
其中倾向于了关于客户端和服务端等待超时的设置,那就试试修改一下等待超时时常的设置吧,
我使用的客户端的调用的方法如下:
1 public static String doDownloadRecipeInfo(String username,String password ,String senderCode ) { 2 3 String result = ""; 4 String url =XmlUtil.queryInfo(1).getWebserviceURL();//通过公共类获取webservice的URL 5 String qname=XmlUtil.queryInfo(1).getQname();//通过公共类获取webservice发布的服务名 6 7 8 try { 9 10 logger.setLevel(Level.DEBUG); 11 Service service = new Service(); 12 Call call = (Call) service.createCall(); 13 call.setTargetEndpointAddress(new java.net.URL(url)); 14 call.setOperationName(new QName(qname, "doDownloadRecipeInfo")); 15 call.addParameter("userName", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); 16 call.addParameter("password", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); 17 call.addParameter("senderCode", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); 18 call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING); 19 call.setUseSOAPAction(true); 20 call.setTimeout(1000*200);//设置客户端的等待超时时间 21 22 call.setSOAPActionURI(qname+"doDownloadRecipeInfo"); 23 24 25 26 27 result = (String) call.invoke(new Object[]{username,password ,senderCode}); 28 } catch (Exception e) { 29 e.printStackTrace(); 30 //logger.error("调用平台接口方法doDownloadRecipeStatusInfo失败", e); 31 } 32 // logger.info("返回信息" + result); 33 if(result!=null&& result.length()>0){ 34 System.out.println(result); 35 } 36 return result; 37 } 38
服务端的设置,在服务端的tomcat下的conf文件夹下的 server.xml中修改连接超时时长
<Connector port="18558" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8444" /> <!-- 将上面中的connectionTimeout参数调整的大一点 -->
然后尝试执行客户端的程序调用服务端的方法,但是执行了几分钟之后仍然报错,连接被挂掉了!
因为调用webservice方法之后返回的XML格式的数据太长了,我想从简单的验证,就将返回的XML格式的数据弄短了些,让后仍然将等待时间设置长了点,重新执行客户端的程序之后数据成功获取到了;为了验证是等待超时的问题还是数据太长的原因,我将等待超时设置默认的值,然后重新调用webservice,结果是失败;然后我又将等待时长调大,然后将返回的XML数设置长,测试的结果是连接又被干掉了!
让后我在网上了解,看到有人在网上回答:数据太大的话,比如一下返回的数据是10M的,网络连接很快就会被挂掉了!
同时,经验证,如果数据稍微大点,比如3-4M,有时候可以通过稍微调大等待超时时长来解决问题,但是如果数据偏大的话,比如10M,调大等待超时时长也无济于事,Socket连接很快会被干掉,只要数据一直这么大,连接就会被不断的干掉。
所以经过不断调试,调整了webservice方法返回的数据的大小,并稍微调大了等待超时时长,再次运行服务端和客户程序之后,数据稳定的进行处理和传输。
总结:webservice只适用于小数据的传输,不要尝试使用webservice进行大数据的传输。