最近在測試Nginx進行負載均衡和集群模式下自己發布的WebService服務,
簡單的調用代碼如下:
1 String operation = "sayHello"; 2 String nameSpace = "http://www.test.com/service"; 3 String endPoint = "http://ip:port/test-console/jbi/ExampleService/main?wsdl"; 4 String ret = WebServiceUtil.invoke(endPoint, nameSpace, new Object[] { "World Timer" }, operation, 5 String.class, 360000);
在單機非Nginx下,調用我們自己發布的服務,一點錯誤都沒有,運行很正常。但在Nginx集群和負載均衡下在調用的時候報如下錯誤
org.apache.axis2.AxisFault: Transport error: 411 Error: Length Required
at org.apache.axis2.transport.http.HTTPSender.handleResponse(HTTPSender.java:296)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:190)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:371)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:209)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:448)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:401)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:548)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:528)
at org.apache.axis2.rpc.client.RPCServiceClient.invokeBlocking(RPCServiceClient.java:76)
at com.ygsoft.soaware.util.WebServiceUtil.invoke(WebServiceUtil.java:235)
at com.ygsoft.test.HelloWorldInvokeServiceTest.testInvoke(HelloWorldInvokeServiceTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
又或者是
org.apache.axis2.AxisFault: Software caused connection abort: recv failed
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:193)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:371)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:209)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:448)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:401)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:548)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:528)
at org.apache.axis2.rpc.client.RPCServiceClient.invokeBlocking(RPCServiceClient.java:76)
at com.ygsoft.soaware.util.WebServiceUtil.invoke(WebServiceUtil.java:235)
at com.ygsoft.test.HelloWorldInvokeServiceTest.testInvoke(HelloWorldInvokeServiceTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.readLine(MultiThreadedHttpConnectionManager.java:1413)
at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973)
at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:542)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:189)
... 31 more
反編譯自己的WebServiceUtil工具類,調用代碼如下:
1 public static String invoke(String epr, String namespace, Object[] parameters, String operation, 2 Class<?> returnType, long timeoutMilliseconds) throws AxisFault { 3 RPCServiceClient serviceClient = new RPCServiceClient(); 4 Options options = serviceClient.getOptions(); 5 options.setTimeOutInMilliSeconds(timeoutMilliseconds); 6 EndpointReference targetEPR = new EndpointReference(epr); 7 options.setTo(targetEPR); 8 if (log.isDebugEnabled()) 9 startTime = System.currentTimeMillis(); 10 11 OMElement om = serviceClient.invokeBlocking(new QName(namespace, operation), parameters); 12 if (log.isDebugEnabled()) { 13 endTime = System.currentTimeMillis(); 14 log.debug("服務調用耗時為:" + ((endTime - startTime) / 1000.0D) + "'s"); 15 } 16 return null2blank(om); 17 } 18 19 public static String null2blank(Object obj) { 20 return ((obj == null) ? "" : obj.toString()); 21 }
通過反編譯WebServiceUtil工具類發現,我的工具類缺少個屬性設置,只要在調用代碼里面加上如下的代碼:
options.setProperty(HTTPConstants.CHUNKED, false);
完善后的代碼如下:
1 public static String invoke(String epr, String namespace, Object[] parameters, String operation, 2 Class<?> returnType, long timeoutMilliseconds) throws AxisFault { 3 RPCServiceClient serviceClient = new RPCServiceClient(); 4 Options options = serviceClient.getOptions(); 5 //注意這里 6 options.setProperty(HTTPConstants.CHUNKED, false); 7 options.setTimeOutInMilliSeconds(timeoutMilliseconds); 8 EndpointReference targetEPR = new EndpointReference(epr); 9 options.setTo(targetEPR); 10 if (log.isDebugEnabled()) 11 startTime = System.currentTimeMillis(); 12 13 OMElement om = serviceClient.invokeBlocking(new QName(namespace, operation), parameters); 14 if (log.isDebugEnabled()) { 15 endTime = System.currentTimeMillis(); 16 log.debug("服務調用耗時為:" + ((endTime - startTime) / 1000.0D) + "'s"); 17 } 18 return null2blank(om); 19 } 20 21 public static String null2blank(Object obj) { 22 return ((obj == null) ? "" : obj.toString()); 23 }
完善后上面的問題,就迎刃而解了。