Я провел день, борясь с этой очень странной проблемой.Вот мой очень простой метод контроллера:
@GetMapping("/bigfile")
public ResponseEntity<byte[]> big() {
final byte[] someBytes = new byte[10 * 1000 * 1000];
LOG.info("I want to write: " + someBytes.length + " bytes");
final HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentLength(someBytes.length);
httpHeaders.setContentType(IMAGE_PNG);
return new ResponseEntity<>(someBytes, httpHeaders, OK);
}
Очень простой материал.Он отправляет 10 Мбайт нулевых байтов как PNG.Это должно "просто работать" легко.(Очевидно, что это недопустимые изображения PNG. Моя цель - отправить в качестве примера длинный байтовый массив.) И это так.Он отлично работает.
Пока я не переключу Tomcat на использование HTTP / 2, добавив:
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
keepAliveTimeout="20000"/>
в конфигурацию хоста.Затем он начинает разрывать соединение после примерно 1 Мб до 3 Мб передачи, и я вижу такие ошибки, как:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:333) ~[catalina.jar:9.0.12]
at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:728) ~[catalina.jar:9.0.12]
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:657) ~[catalina.jar:9.0.12]
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:368) ~[catalina.jar:9.0.12]
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:346) ~[catalina.jar:9.0.12]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[catalina.jar:9.0.12]
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:639) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:639) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at java.base/java.io.InputStream.transferTo(InputStream.java:522) ~[na:na]
Это сводит меня с ума.Простое решение состоит в том, чтобы просто не использовать HTTP / 2, что, вероятно, является решением, которое мне нужно использовать.Есть объяснения?Я что-то упустил, или это ошибка в Tomcat HTTP / 2?Для реального производственного использования это подтверждает мне, что я не должен использовать Tomcat в качестве фактического внешнего интерфейса, а скорее я должен использовать Nginx и прокси для Tomcat.Но я надеялся отложить это на потом.