上游连接错误或在标头之前断开/重置。重置原因:使用Spring Boot时连接终止

cod*_*123 4 tomcat spring-boot kubernetes istio

我正在使用带有嵌入式 Tomcat 9.0.36 的 Spring Boot。它在 Kubernetes 中用作 Docker 镜像。最近升级 Envoy 后,我开始遇到异常。

  "upstream connect error or disconnect/reset before headers. reset reason: connection termination" with 503 status code
Run Code Online (Sandbox Code Playgroud)

有些人建议将空闲连接超时增加到 60 秒,但在 spring-boot 中我能够找到“连接超时”和“保持活动超时”。我使用下面的代码将它们增加到 5 分钟。

  "upstream connect error or disconnect/reset before headers. reset reason: connection termination" with 503 status code
Run Code Online (Sandbox Code Playgroud)

尽管如此,我还是遇到了同样的错误。该应用程序在内部调用另一个同样托管在 Kubernetes 中的服务。我可以在我的服务中看到成功的响应,但之后我看不到任何日志。

cod*_*123 7

我花了一周的时间从应用的角度分析这个问题。我遵循了运营团队建议的几个步骤。

  • 将 Tomcat 服务器中的超时增加到 60 秒,因为他们在 Envoy 中进行了相同的配置
  • 我确实增加了时间,但无法解决问题。
  • 我使用 Spring Cloud Gateway 进行网关服务,我认为这是问题所在,所以我将其更改为 Rest Templates,但这也没有解决问题。
  • 幸运的是,健康检查 API 工作正常,除了那些在内部与其他服务通信的 API 之外。在 Health API 中,他们还与其他服务进行通信以检查其健康状况,但我没有直接返回响应。我正在包装响应正文并对其进行修改并将其转发到 UI。我还应用了相同的方法并使用下面的代码,您可以轻松理解。我创建了一个新的响应实体,并删除了从内部 API 收到的所有标头并返回到 UI。它就像魅力一样起作用。

//Earlier (Forwarding same headers received from internal service to UI)
ResponseEntity responseEntity = //Received by calling other APIs;
return responseEntity;

//Now (Dropped headers)
ResponseEntity responseEntity = //Received by calling other APIs;
MultiValueMap<String, String> newHeaders = new LinkedMultiValueMap<>();          
if (Objects.nonNull(responseEntity) && Objects.nonNull(responseEntity.getBody())) {
    newHeaders.set("Content-type", responseEntity.getHeaders().getContentType().toString());
    return new ResponseEntity(responseEntity.getBody(), newHeaders, responseEntity.getStatusCode());
}
Run Code Online (Sandbox Code Playgroud)