使用restTemplate时线程被阻塞

5

我遇到了一个问题,当使用Spring的RestTemplate与远程服务器通信时,我的应用程序的线程被锁定/阻塞。

以下是一个被阻塞线程的jstack信息:

"pool-1-thread-8" prio=10 tid=0x00007fbfd012d800 nid=0x27b1 runnable [0x00007fbfd7dfb000]
   java.lang.Thread.State: RUNNABLE
        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.read1(BufferedInputStream.java:258)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
        - locked <0x00007fbfe40fe1f8> (a java.io.BufferedInputStream)
        at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
        at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1072)
        - locked <0x00007fbfe40fe2f0> (a sun.net.www.protocol.http.HttpURLConnection)
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373)
        at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:47)
        at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:32)
        at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:55)
        at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:49)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:489)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
        at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:302)
        at com.xxx.activation.service.action.impl.RestServiceImpl.sendContactRequest(RestServiceImpl.java:37)
        at com.xxx.activation.service.action.impl.SendContactRequestAction.perform(SendContactRequestAction.java:125)
        at com.xxx.activation.service.action.impl.DefaultStateActionService.doAction(DefaultStateActionService.java:75)
        at com.xxx.activation.service.action.impl.ActionProcess$StateActionTask.call(ActionProcess.java:54)
        at com.xxx.activation.service.action.impl.ActionProcess$StateActionTask.call(ActionProcess.java:41)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)


如何解决这个问题?
这与java.net.URLConnection的readTimeout有关吗?
在使用Spring的RestTemplate时,默认的connectTimeoutreadTimeout的底层套接字是什么?

提前感谢。


我认为你没有连接到远程套接字的权限... - webcoder
你的 restTemplate 尝试访问的是什么资源?访问它是否是线程安全的操作? - Nikhil Talreja
你的堆栈跟踪清楚地显示了线程在java.net.SocketInputStream.socketRead0中被阻塞,而不是RestTemplate本身。你是否期望网络I/O有时不会被阻塞? - Raedwald
请参见http://stackoverflow.com/questions/28494203/blocked-thread-while-executing-oracle-procedure-from-java-class。 - Raedwald
2个回答

1
如果您使用默认的Rest Template,请将读取超时时间添加到默认请求工厂中,当前默认为SimpleClientHttpRequestFactory。
final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setReadTimeout(10_000);  // 10 sec as needed by us
    final RestTemplate restTemplate = new RestTemplate(requestFactory);

如果不行的话,请检查http连接的readTimeout值是否为0,并给它赋一个值。

0

这个链接描述了你的问题

尝试为你的 REST 调用设置一个超时时间,并确保 REST 服务在运行中。检查一下你的 REST 服务是否正在尝试获取大量信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接