Axis2 WebService 客户端访问超时,尝试连接3次

本文详细介绍了如何解决在使用移动短信发送程序时遇到的远程服务器连接超时问题,通过分析异常堆栈和相关代码,最终定位到commons-httpclient-3.1.jar中HttpMethodDirector类的executeWithRetry方法。文章提供了具体的修改策略,并展示了通过替换jar包中的类来解决该问题的方法。此外,还强调了在业务需求下避免不必要的重试访问的重要性。
摘要由CSDN通过智能技术生成

      近段时间因做移动的短信发送程序,需要连接到远程的Web Services进行发送短信操作。发现怪现象当我连接的远程服务器出现ping不同的场合下出现连接超时的异常,异常很正常,但是查看异常代码发现它在出现连接超时的场合下,进行了3次尝试行的连接。异常如下:

 

(httpclient.HttpMethodDirector       439 ) I/O exception (java.net.ConnectException) caught when processing request: Connection timed out: connect
(httpclient.HttpMethodDirector       445 ) Retrying request
(httpclient.HttpMethodDirector       439 ) I/O exception (java.net.ConnectException) caught when processing request: Connection timed out: connect
(httpclient.HttpMethodDirector       445 ) Retrying request
(httpclient.HttpMethodDirector       439 ) I/O exception (java.net.ConnectException) caught when processing request: Connection timed out: connect
(httpclient.HttpMethodDirector       445 ) Retrying request
(http.HTTPSender                     192 ) Unable to sendViaPost to url[http://10.64.92.24:8501/lbs_sms_interfacehW2/service/UserGateInfoService]
java.net.ConnectException: Connection timed out: connect
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
	at java.net.Socket.connect(Socket.java:519)
	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:597)
	at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:140)
	at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:125)
	at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
	at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
	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)
	at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:364)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:208)
	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 com.cmcc.lbs.ug.interfaces.infomomt.UserGateInfoServiceStub.sendSms(UserGateInfoServiceStub.java:468)
	at com.neusoft.avnc.lbs.autonavi.server.business.messageSend.mt.SimpleClient.main(SimpleClient.java:62)
org.apache.axis2.AxisFault: Connection timed out: connect
	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:364)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:208)
	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 com.cmcc.lbs.ug.interfaces.infomomt.UserGateInfoServiceStub.sendSms(UserGateInfoServiceStub.java:468)
	at com.neusoft.avnc.lbs.autonavi.server.business.messageSend.mt.SimpleClient.main(SimpleClient.java:62)
Caused by: java.net.ConnectException: Connection timed out: connect
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
	at java.net.Socket.connect(Socket.java:519)
	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:597)
	at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:140)
	at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:125)
	at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
	at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
	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)
	... 9 more


因业务需要,需要改成异常了无需进行尝试访问,在查看了以上的异常和相关大量代码,终于找到了修改的地方,找到工程引用的jar包:commons-httpclient-3.1.jar

找到 这个类:HttpMethodDirector的executeWithRetry方法,源代码如下:(注意第45行代码)

    private void executeWithRetry(HttpMethod method)
        throws IOException, HttpException
    {
        int execCount = 0;
_L2:
        execCount++;
        if(LOG.isTraceEnabled())
            LOG.trace("Attempt number " + execCount + " to process request");
        if(conn.getParams().isStaleCheckingEnabled())
            conn.closeIfStale();
        if(!conn.isOpen())
        {
            conn.open();
            if(conn.isProxied() && conn.isSecure() && !(method instanceof ConnectMethod) && !executeConnect())
                return;
        }
        try
        {
            try
            {
                applyConnectionParams(method);
                method.execute(state, conn);
                break MISSING_BLOCK_LABEL_452;
            }
            catch(HttpException e)
            {
                throw e;
            }
            catch(IOException e)
            {
                LOG.debug("Closing the connection.");
                conn.close();
                HttpMethodRetryHandler handler;
                if(method instanceof HttpMethodBase)
                {
                    handler = ((HttpMethodBase)method).getMethodRetryHandler();
                    if(handler != null && !handler.retryMethod(method, conn, new HttpRecoverableException(e.getMessage()), execCount, method.isRequestSent()))
                    {
                        LOG.debug("Method retry handler returned false. Automatic recovery will not be attempted");
                        throw e;
                    }
                }
                handler = (HttpMethodRetryHandler)method.getParams().getParameter("http.method.retry-handler");
                if(handler == null)
                    handler = new DefaultHttpMethodRetryHandler();
                   if(!handler.retryMethod(method, e, execCount))
                {
                    LOG.debug("Method retry handler returned false. Automatic recovery will not be attempted");
                    throw e;
                }
                if(LOG.isInfoEnabled())
                    LOG.info("I/O exception (" + e.getClass().getName() + ") caught when processing request: " + e.getMessage());
                if(LOG.isDebugEnabled())
                    LOG.debug(e.getMessage(), e);
                LOG.info("Retrying request");
            }
        }
        catch(IOException e)
        {
            if(conn.isOpen())
            {
                LOG.debug("Closing the connection.");
                conn.close();
            }
            releaseConnection = true;
            throw e;
        }
        catch(RuntimeException e)
        {
            if(conn.isOpen())
            {
                LOG.debug("Closing the connection.");
                conn.close();
            }
            releaseConnection = true;
            throw e;
        }
        if(true) goto _L2; else goto _L1
_L1:
    }


也就是说当header为null的场合下进行了DefaultHttpMethodRetryHandler实例化

在看看这个类的源代码:(注意第23行代码)

package org.apache.commons.httpclient;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;

// Referenced classes of package org.apache.commons.httpclient:
//            HttpMethodBase, NoHttpResponseException, HttpMethodRetryHandler, HttpMethod

public class DefaultHttpMethodRetryHandler
    implements HttpMethodRetryHandler
{

    public DefaultHttpMethodRetryHandler(int retryCount, boolean requestSentRetryEnabled)
    {
        this.retryCount = retryCount;
        this.requestSentRetryEnabled = requestSentRetryEnabled;
    }

    public DefaultHttpMethodRetryHandler()
    {
        this(3, false);
    }

    public boolean retryMethod(HttpMethod method, IOException exception, int executionCount)
    {
        if(method == null)
            throw new IllegalArgumentException("HTTP method may not be null");
        if(exception == null)
            throw new IllegalArgumentException("Exception parameter may not be null");
        if((method instanceof HttpMethodBase) && ((HttpMethodBase)method).isAborted())
            return false;
        if(executionCount > retryCount)
            return false;
        if(exception instanceof NoHttpResponseException)
            return true;
        if(exception instanceof InterruptedIOException)
            return false;
        if(exception instanceof UnknownHostException)
            return false;
        if(exception instanceof NoRouteToHostException)
            return false;
        if(SSL_HANDSHAKE_EXCEPTION != null && SSL_HANDSHAKE_EXCEPTION.isInstance(exception))
            return false;
        return !method.isRequestSent() || requestSentRetryEnabled;
    }

    public boolean isRequestSentRetryEnabled()
    {
        return requestSentRetryEnabled;
    }

    public int getRetryCount()
    {
        return retryCount;
    }

    private static Class SSL_HANDSHAKE_EXCEPTION = null;
    private int retryCount;
    private boolean requestSentRetryEnabled;

    static 
    {
        try
        {
            SSL_HANDSHAKE_EXCEPTION = Class.forName("javax.net.ssl.SSLHandshakeException");
        }
        catch(ClassNotFoundException ignore) { }
    }
}

发现倪端了吧。

根据自己的需要进行修改,然后生成class,替换jar包中相应的类就可以了。

如果还有其他问题,欢迎联系我。

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值