Загрузка большого (1 ГБ) файла с сервера приводит к превышению времени ожидания запроса - PullRequest
1 голос
/ 09 апреля 2020

Итак, я разрабатываю 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 был на этой проблеме в течение прошлой недели, и я постепенно схожу с ума. пожалуйста помогите :(

с уважением

...