resttemplate Connection timed out 和 SocketTimeoutException

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/davidmeng6628/article/details/79098980

最近开始使用resttemplate 调用一些其他rest 服务。

之前公司默认的timeout时间是20秒。然后就在网上搜了一个方法设置了连接超时时间。方法如下,

    <bean id="requestFactory"
        class="org.springframework.http.client.SimpleClientHttpRequestFactory">
        <property name="readTimeout" value="20000" />
        <property name="connectTimeout" value="20000" />
    </bean>


    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <constructor-arg ref="requestFactory" />
    </bean>
并没有仔细研究就使用了。

然后上了生产环境以后,发现有些超时时间只有7秒。(到现在为止我也不知道这个7秒是怎么来的)。超时log如下。

09-Jan-2018 10:42:44.219 SEVERE [http-nio-6021-exec-10] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [/XXX] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://xxxxxxxxxx/api/xxxxxxx": Connection timed out (Connection timed out); nested exception is java.net.ConnectException: Connection timed out (Connection timed out)] with root cause
 java.net.ConnectException: Connection timed out (Connection timed out)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:668)
	at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)
	at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)
	at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1138)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1032)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
然后排查其他的application,发现有的超时时间竟然是20秒,error log如下,

18-Jan-2018 11:56:51.344 SEVERE [http-nio-6026-exec-3] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [/xxxx] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://xxxx/risk/api/xxx/xxx":Read timed out; nested exception is java.net.SocketTimeoutException: Read timed out] with root cause
 java.net.SocketTimeoutException: Read timed out
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:170)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
	at sun.security.ssl.InputRecord.read(InputRecord.java:503)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
	at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:80)
	at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
	at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:596)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:572)
	at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:400)
经过排查,两个timeout不一样,一个是connection time out,一个是 sockettimeout。网上查询得知第一个是网络连接时间,第二个是网络连接后得到服务器相应时间。

而resttempalte 设置只能设置sockettimeout。没有办法设置connection time out,我自己并没有找到其他timeout参数设置。

然后改用httpclient连接。spring配置文件如下,

    <bean id="requestFactory"
        class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
        <property name="readTimeout" 				value="20000" />
        <property name="connectTimeout" 			value="20000" />
        <property name="connectionRequestTimeout" 	value="20000" />
    </bean>

    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <constructor-arg ref="requestFactory" />
    </bean>

希望新的配置方式可以起到作用,后续结果会更新。





阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页