【问题标题】:Connection reset by peer io.netty.channel.unix.Errors$NativeIoException对等 io.netty.channel.unix.Errors$NativeIoException 重置连接
【发布时间】:2020-02-25 04:31:20
【问题描述】:

我正在使用来自 spring-boot-starter-webflux 的 WebClient。我一直在生产环境中看到来自 reactor netty 的对等错误重置连接。然后 reactor netty 在几秒钟(~10-20 秒)后重试这个失败的请求。我没有看到或无法在较低的环境中重现此错误。我无法确定这个错误的根本原因,在这里我提供了我的 ClientHelper 实现和错误日志,

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;

public class ClientHelper {

  protected WebClient webClient;

  public <T> T post(Object request, TypeReference typeReference,
                    String uri) {
    try {
      ObjectMapper objectMapper = new ObjectMapper();
      String body = objectMapper.writeValueAsString(request);
      ClientResponse clientResponse =
              getWebClient()
                      .post()
                      .uri(uri)
                      .body(BodyInserters.fromObject(body))
                      .exchange()
                      .block();
      return prepareResponse(clientResponse, typeReference, objectMapper);
    } catch (Exception e) {
      return handleException(e);
    }
  }

  protected <T> T prepareResponse(ClientResponse clientResponse, TypeReference typeReference,
                                  ObjectMapper objectMapper) throws Exception {
    String responseText = clientResponse.bodyToMono(String.class).block();
    if (clientResponse.statusCode() == HttpStatus.OK) {
      return objectMapper.readValue(responseText, typeReference);
    } else {
      throwNewException("Remote service returned a message with statusCode = "
              + clientResponse.statusCode() + "; response = " + responseText,  null);
      return null;
    }
  }

  protected <T> T handleException(Exception e) {
    throwNewException("Communication error. Cause: " + e.getMessage(), e);
    return null;
  }

  protected void throwNewException(String message, Throwable cause) {
    throw new RuntimeException(message, cause);
  }

  public WebClient getWebClient() {
    return WebClient.builder().baseUrl("http://app.corp.com/").build();
  }
2019-10-29 20:56:20,383 DEBUG r.u.Loggers$Slf4JLogger [reactor-http-epoll-8] [] [id: 0x65cf7989, L:/xx.xx.xxx.xxx:xxxxx - R:app.corp.com/xx.xx.xx.xx:xxx] The connection observed an error, the request will be retried
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer

spring-boot-starter-webflux: 2.1.9.RELEASE, 反应堆网络:0.8.12.RELEASE

如果此实施存在问题和/或如何进一步分类此问题,请告诉我。

【问题讨论】:

  • 我在我的 prod 环境中遇到了类似的问题,在较低的环境中确实无法始终如一地重新创建。对此有任何了解吗?
  • 我升级到最新的 Spring Boot 版本并添加了 Webclient 的连接超时来解决问题。
  • 你可以分享你使用的连接超时配置和弹簧启动版本.. bcz 我面临同样的问题。谢谢
  • 我添加了 ReadTimeoutHandler、WriteTimeoutHandler、IdleStateHandler 和 10 秒作为超时配置。 Spring Boot 版本为 2.1.9.RELEASE。

标签: spring-boot spring-webflux reactor-netty


【解决方案1】:

您会在生产中看到此问题的一个原因是 SSL。尝试配置 SSL 超时

例如下面的设置是针对使用netty的spring cloud gateway:

https://cloud.spring.io/spring-cloud-gateway/multi/multi__tls_ssl.html

spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          handshake-timeout-millis: 10000
          close-notify-flush-timeout-millis: 3000
          close-notify-read-timeout-millis: 0

https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-webclient-reactor-netty-customization

【讨论】:

  • 我在几个生产实例中切换到 http 并重现了同样的问题。所以 SSL 不是问题的根本原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多