java - HttpClient 超时

标签 java spring httpclient httpinvoker

我有一个使用 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>

**更新解决方案 看起来 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>

最佳答案

您无法设置最大请求持续时间。 This有一些有用的信息。

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

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

关于java - HttpClient 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17606827/

相关文章:

java - 用于处理 HttpClient 上传的文件的服务器代码

java - 使用数据 JPA 和 CrudRepository 只保存而不更新

java - Apache HTTP 客户端和 Google HTTP 客户端有什么区别?

Java 二进制兼容性问题 : sun. font.FontManager 类成为接口(interface)

java - 如何使用我的 ID 保存实体

java - AWS SDK KMS - 在 Nodejs 中加密并在 Java 中解密

javax.net.ssl.SSLException : hostname in certificate didn't match in conjunction with Apache httpd virtual hosts 异常

java - Math.pow 和 Math.sqrt 公式返回值 0

java - 使用 spring @Caching 时缓存层的顺序是什么?

http - 使用 HttpClient 阻止下载整个远程资源?