Итак, я разрабатываю 2 услуги. Один сервис обрабатывает файл в файловой системе и возвращает их через интерфейс REST. ServiceA:
File zipFile = new File(folderDownload.getZipPath());
try {
final InputStream inputStream = new BufferedInputStream(new FileInputStream(zipFile));
return ResponseEntity
.status(HttpStatus.OK)
.eTag(folderDownload.getDownloadId())
.contentLength(zipFile.length())
.lastModified(Instant.ofEpochMilli(zipFile.lastModified()))
.body(new InputStreamResource(inputStream));
} catch (Exception e) {
throw new DownloadException(zipFile.getName(), e.getMessage(), 400);
}
ServiceB - это общедоступный c API-интерфейс, который принимает запросы, проверяет их, и, если запрос действителен, он получает файлы из serviceA и возвращает их клиенту. В целях безопасности serviceA может взаимодействовать только с serviceB, поэтому нет другого пути, кроме отправки файла через 2 службы ...
WebClient client = WebClient.create(STORAGE_HOST);
// Request service to get file data
Flux<DataBuffer> fileDataStream = client.get().uri(uriBuilder -> uriBuilder.path("folders/zip/download").queryParam("requestId", requestId).build())
.accept(MediaType.APPLICATION_OCTET_STREAM).retrieve()
.bodyToFlux(DataBuffer.class);
// Streams the stream from response instead of loading it all in memory
DataBufferUtils.write(fileDataStream, outputStream).map(DataBufferUtils::release).then().block();
При загрузке небольших файлов все в порядке. При загрузке больших файлов я получал исключение из памяти на serviceB. Я начал использовать webClient вместо restTemplate, и эти проблемы исчезли. Но теперь я столкнулся с новой проблемой:
Если файл большой, время ожидания запроса до его завершения. Таким образом, пользователь получает неполный файл. Какое решение здесь?
Исключение, которое я вижу в консоли на сервисе B:
2020-04-09 13:40:24.138 WARN 4106 --- [io-8081-exec-10] s.a.s.e.CustomGlobalExceptionHandler : Async request timed out
2020-04-09 13:40:24.138 WARN 4106 --- [io-8081-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.context.request.async.AsyncRequestTimeoutException]
Также я нахожу странным, что при загрузке напрямую из сервиса A у меня нет индикатора загрузки ...
I был на этой проблеме в течение прошлой недели, и я постепенно схожу с ума. пожалуйста помогите :(
с уважением