1

我有一个使用 spring HttpInvokers 的客户端服务器应用程序。我正在与超时作斗争。我看到有关此的其他线程,但没有明确的答案。

据我所知, readTimeout 应该在它已经连接后控制事务的长度。我做了很长时间,因为某些流程(例如报告请求)需要时间来运行。这在很长一段时间内都运行良好。

现在的问题是,有时互联网连接会在发出请求时失败或突然中断,并且永远不会建立连接。我没有出错,而是建立了一个重试程序,它拦截失败的连接并重试它。我希望这些故障快速发生,因此我将 HttpClient 参数soTimeoutconnectionManagerTimeout设置为 2 秒。

这似乎在大多数情况下都有效。有时需要超过 2 秒才能发现问题,但这没关系。问题是 soTimeout 似乎也适用于或覆盖 readTimout。所以现在我所有运行时间较长的请求都获得了重试功能,即使它们连接得很好并且只是在等待回复完成。connectionManagerTimeout 设置似乎什么都不做。似乎没有什么影响实际获取初始连接所需的时间。

我应该设置另一个超时参数吗?

 <bean id="myServiceInterceptor"
          class="org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor">
        <property name="serviceUrl">
            <value>https://myhost/myservices/myMgrService</value>
        </property>
        <property name="remoteInvocationFactory" ref="remoteInvocationFactory"/>
        <property name="httpInvokerRequestExecutor">
 <bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor">
                <!--read time out is how long we will wait for a reply.  This is large in case we are waiting on a long server process-->
                <property name="readTimeout" value="2000000"/>
                <!--                we manually set this so we can control the parameter timeout values-->
                <property name="httpClient">
                    <bean class="org.apache.commons.httpclient.HttpClient">
                        <constructor-arg index="0">
                            <!--we want multi threaded if we want to ever connect in background threads, this is default if not set anyways in CommonsHttpInvokerRequestExecutor but since we are overriding we have to manually set it or we get the simple one-->
                            <bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"></bean>
                        </constructor-arg>
                        <property name="params">
                            <bean class="org.apache.commons.httpclient.params.HttpClientParams">
                                <!--Here we set the socket time out and connection manager time out which is how long we wait for the socket to connect before showing bad feedback.
             The default is 60 seconds which makes the client just hang.  Now we get immediate response from our RetryConnection-->
                                <property name="soTimeout" value="2000"/>
                                <property name="connectionManagerTimeout" value="2000"/>
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>        </property>
    </bean>
    <bean id="myServiceMgr" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="interceptorNames">
            <list>

                <value>clientExceptionAdvisor</value>
                <value>retryConnection</value>
                <value>myServiceInterceptor</value>
            </list>
        </property>
        <property name="proxyInterfaces">
            <value>ServiceIF</value>
        </property>
    </bean>

* *UPDATE SOLUTION 看起来soTimout 也是读取超时。有一种方法可以设置连接超时,这只是一种痛苦。这是我使用的spring xml:

<bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor">
                <!--read time out is how long we will wait for a reply.  This is large in case we are waiting on a long server process-->
                <property name="readTimeout" value="2000000"/>
                <!--                we manually set this so we can control the parameter timeout values-->
                <property name="httpClient">
                    <bean class="org.apache.commons.httpclient.HttpClient">
                        <constructor-arg index="0">
                            <bean class="org.apache.commons.httpclient.params.HttpClientParams">
                                <!--Here we set the connection manager time out which is supposed to be how long we wait for the established connection to be returned from the connection manager. This shortness allows us to catch it and enable the retry function.-->
                                <property name="connectionManagerTimeout" value="2500"/>
                            </bean>
                        </constructor-arg>
                        <constructor-arg index="1">
                            <!--we want multi threaded if we want to ever connect in background threads, this is default if not set anyways in CommonsHttpInvokerRequestExecutor but since we are overriding we have to manually set it or we get the simple one-->
                            <bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
                                <property name="params">
                                    <bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">
                                        <!--Here we set the socket time out which is essentially the same thing as the readTimeout.  It is the time we wait for a response-->
                                        <property name="soTimeout" value="2000000"/>
                                        <!--Here we set the connection time out which is supposed to be how long we wait for the connect to be established. This shortness allows us to catch it and enable the retry function.  The default is 60 seconds which makes the client just hang.  -->
                                        **<property name="connectionTimeout" value="2500"/>**
                                    </bean>
                                </property>
                            </bean>
                        </constructor-arg>
                        <property name="params">
                            <bean class="org.apache.commons.httpclient.params.HttpClientParams">
                                <!--Here we set the socket time out which is essentially the same thing as the readTimeout.  It is the time we wait for a response-->
                                <property name="soTimeout" value="2000000"/>
                                <!--Here we set the connection manager time out which is how long we wait to get an established connection returned from the connection manager.
             The default is 60 seconds which makes the client just hang.  Now we get more immediate response from our RetryConnection.  But it isn't totally reliable cause of underlying tcp/ip-->
                                **<property name="connectionManagerTimeout" value="2500"/>**
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
4

4 回答 4

1

您不能设置最大请求持续时间。有一些有用的信息。

通常对于 http 连接,无论连接类型如何,您都应该具有相同的超时时间。在不同的时间点对同一事物进行计数是没有意义的。

您应该将 API 设置为预先运行报告,或者在不锁定调用程序的不同线程上运行。这样,您可以取回一个状态对象,让您知道是否需要再次检查报告。

于 2013-07-12T03:54:30.537 回答
0

你可以使用OkHttp并调用

HttpURLConnection connection = okHttpClient.open(new URL(urlStr));
connection.setReadTimeout(60000);
于 2014-01-07T12:09:18.547 回答
0

也许我在这里误解了这个问题,但你不能在调用 sotimeout 之前先检查有效的网络连接吗?或者当你有一个有效的连接时禁用 sotimeout ?

抱歉,如果这无关紧要,我有点累:D

于 2013-07-12T03:59:22.167 回答
-2
Timer timer = new Timer();
timer.schedule(new TimerTask() {
    public void run() {
        if(getMethod != null) {
            getMethod.abort();
        }
    }
}, timeout * 1000);

你可以试试这个来增加你的超时时间。

或者可以更喜欢链接 Apache HttpComponents HttpClient timeout

于 2013-07-12T09:39:01.270 回答