Загрузка файла из Amazon S3 через REST (Jax-RS) - PullRequest
0 голосов
/ 15 мая 2019

Я пытаюсь загрузить файл с Amazon S3.

Я хочу, чтобы пользователь посетил мое приложение через GET API.

Приложение, в свою очередь, получает контент от S3 и возвращает его пользователю в виде загружаемого файла.

Примечание:

Я не хочу хранить файл локально на моем сервере, я хочу, чтобы он транслировался из amazon s3 напрямую конечному пользователю

Я пытался с файлом около 300 МБ, если я запускаю его локально, как показано ниже занимает мало места, т. е. локально присутствует один и тот же файл

   @GET
    @Path("/pdfdownload")
    @Produces("application/pdf")
    public Response getFile() {
    File file = new File('/pathToFile'); // in local

    ResponseBuilder response = Response.ok((Object) file);
    response.header("Content-Disposition", "attachment; filename=file.pdf");
    return response.build();
}

Но когда я загружаю то же самое с Amazon s3, память моего сервера tomcat быстро увеличивается до 600 МБ, я думаю, что я передаю содержимое, но когда я смотрю на используемую память, я сомневаюсь в этом Я что-то упустил?

@GET
@Path("/pdfdownload")
@Produces("application/pdf")
public Response getFile2() {
    final S3Object s3Object = getAmazonS3Object();// AWS S3
    final S3ObjectInputStream s3is = s3Object.getObjectContent();

final StreamingOutput stream = new StreamingOutput() {
    @Override
    public void write(OutputStream os) throws IOException, WebApplicationException {
        byte[] read_buf = new byte[1024];
        int read_len = 0;
        while ((read_len = s3is.read(read_buf)) > 0) {
            os.write(read_buf, 0, read_len);
        }
        os.close();
        s3is.close();
    }
};

ResponseBuilder response = Response.ok(stream);
response.header("Content-Disposition", "attachment; filename=file.pdf");
return response.build();
}

private S3Object getAmazonS3Object() {
    AWSCredentials credentials = new BasicAWSCredentials("accesskey",
            "secretkey");
    try {
        AmazonS3 s3 = new AmazonS3Client(credentials);
        S3Object s3object = s3.getObject(new GetObjectRequest("bucketName", "filename_WithExtension"));
        return s3object;
    } catch (AmazonServiceException e) {
        System.err.println(e.getErrorMessage());
        System.exit(1);
    }
    System.out.println("Done!");
    return null;
}

Пом:

<dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.8</version>
        </dependency>


<dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
            <version>1.11.542</version>
        </dependency>

Аналогично этому S3 скачать pdf - REST API

Я не хочу использовать PreSignedURl: https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html

Пожалуйста, смотрите эту статью о потоковой передаче: https://memorynotfound.com/low-level-streaming-with-jax-rs-streamingoutput/

Может, кто-нибудь поможет, почему память всплывает?

1 Ответ

0 голосов
/ 16 мая 2019

Спасибо всем постам на stackoverflow и одному моему коллеге. Мой коллега нашел ответ, на самом деле в приведенном выше коде нет проблемы с памятью, когда я наблюдал за jvm, я увидел всплеск, но не понял, что сборка мусора не началась.

Я попытался загрузить 6 файлов каждый на 300 МБ +, сервер держится на своем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...