RestTemplate.exchange:锁定线程

奎师那日

我正在使用 RestTemplate 与 API 对话。最近我遇到了这个问题,几乎 90% 的线程都处于等待状态。

p685934-2328" #2328 prio=5 os_prio=0 tid=0x00000000023b6000 nid=0x2f1f waiting on condition [0x00007f6df703f000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000ab0eaae8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:380)
    at org.apache.http.pool.AbstractConnPool.access$200(AbstractConnPool.java:69)
    at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:246)
    - locked <0x00000000e728c1e8> (a org.apache.http.pool.AbstractConnPool$2)
    at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:193)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:303)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:279)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:191)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
    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:723)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:600)

RestTemplate 定义如下。

HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout( 3000 );
clientHttpRequestFactory.setReadTimeout( 3000 );

SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial((X509Certificate[] chain, String authType) -> true)
                .build();

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
              sslContext, (String hostname, SSLSession session) -> true);
clientHttpRequestFactory.setHttpClient(HttpClients.custom()
              .setSSLSocketFactory(sslsf).build());



RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);

附加信息

Spring boot version : 2.0.3.RELEASE

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.5</version>
</dependency>

每分钟将有超过 500 个请求来自 RestTemplate。

有关此 API 出了什么问题的任何帮助。RestTemplate 在任何情况下都不会关闭套接字吗?

谢谢,哈里

布鲁克斯德

我认为 90% 的线程处于锁定状态的原因是线程被阻塞/等待 API 响应。根据文档, RestTemplate 是阻塞的或同步的:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

您可以切换到异步或非阻塞 WebClient,并且每个线程应该获得更好的吞吐量:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.html

如果可能的话,另一种选择是为每个连接生成一个线程,但我认为如果您能够移植代码,异步客户端会更好地扩展。

干杯,

凯尔

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

resttemplate.exchange()如何在不同的线程上执行?

RestTemplate线程安全吗?

无法模拟 RestTemplate.exchange

暧昧方法调用嘲讽RestTemplate.exchange()

RestTemplate.exchange()不编码“ +”吗?

RestTemplate JUNIT Exchange方法无法解决

resttemplate.exchange抛出空指针异常

如何测试RestTemplate的线程安全性?

restTemplate.exchange不会解组完整的对象,而只是解封顶层对象-替代restTemplate?

RestTemplate.exchange 无法正常工作。缺少参数抛出

模拟RestTemplate.exchange()方法给出空值

模拟RestTemplate.exchange()给出URI不是绝对异常

RestTemplate-> Exchange产生:422无法处理的实体

一旦线程中断,如何中断RestTemplate调用?

从邮递员Spring Mvc获取时未从resttemplate.exchange获取响应正文

通过resttemplate Exchange在POST请求的正文中发送参数和列表

如何在Spock Groovy中模拟RequestEntity.put()和restTemplate.exchange()

在restTemplate.exchange期间如何从字符串返回特定对象?

如何在Mockito测试中修复RestTemplate.exchange的空值响应?

org.springframework.web.client.HttpClientErrorException: 400 Bad Request 使用 HttpEntity restTemplate.exchange

WebClient与RestTemplate

春天restTemplate

如何在多线程环境中有效使用RestTemplate?

cURL在访问GitHub / search / users API时有效,但使用restTemplate.exchange返回零用户

在使用httpMethod.POST进行restTemplate.exchange之后调用时,为什么HttpStatusCodeException.getResponseBodyAsString()为空

Python线程。如何锁定线程?

线程和锁定资源

Erlang NIF:线程锁定

同步线程和锁定