【问题标题】:SpringTemplate with Jdk 11 throws Connection reset exeception intermittently带有 Jdk 11 的 Spring 模板间歇性地抛出连接重置异常
【发布时间】:2019-12-28 06:39:22
【问题描述】:

我正在使用 Spring RestTemplate 对另一个服务(NodeJS 服务)进行休息调用。间歇性地收到连接重置错误。升级到 Amazon Corretto JDK 11 和 Spring boot 2.1.5 后,相同的代码在 JDK 8 和 Spring boot 2.0.1 上运行良好,开始看到这个问题。

Caused by: javax.net.ssl.SSLException: Connection reset
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
        at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1314)

抑制的异常:

org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
        ... 143 common frames omitted
        Suppressed: java.net.SocketException: Broken pipe (Write failed)
                at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
                at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
                at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)

一些博客提到 JDK 11 与 TLS1.3 存在问题

  1. 尝试使用-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 进行设置
  2. 尝试使用这些协议将SocketFactory 设置为RestTemplate。
  3. 尝试为重置客户端增加 socketTimeout。

还是没有运气。

#代码:#

HttpHeaders headers = new HttpHeaders();
headers.set(AUTHORIZATION, getHeader());
headers.set(OAuth2AccessToken.ACCESS_TOKEN, token);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<Object> resEntity = null;
resEntity = this.restTemplate.exchange(checkTokenEndpointUrl, 
HttpMethod.GET, entity, Object.class);

它不应该抛出间歇性连接重置错误

【问题讨论】:

标签: spring spring-boot spring-mvc resttemplate java-11


【解决方案1】:

在类路径中添加org.apache.httpcomponents:httpclient 后,我们遇到了类似的问题。这将 RestTemplate 请求工厂从 SimpleClientHttpRequestFactory 隐式更改为 HttpComponentsClientHttpRequestFactory。

指定显式SimpleClientHttpRequestFactory作为请求工厂解决了这个问题:

restTemplate.setRequestFactory(new SimpleClientHttpRequestFactory());

【讨论】:

    【解决方案2】:

    我们在使用 fluent 及其连接池时看到了类似的问题。

    我们最简单的解决方法是将连接池中的保持活动策略限制为 90 秒,然后问题就消失了。这使我相信不再打开的连接看起来是打开的,已移交以供使用,但在使用时它不再打开并崩溃。

    显然,当您增加处理握手等的频率时,这会花费更多,但您也会减少连接重置问题。

    【讨论】:

      猜你喜欢
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多