Почему нам нужно установитьReadLimit (int) в Java-клиенте AWS S3 - PullRequest
0 голосов
/ 11 апреля 2019

Я работаю над библиотекой AWS Java S3.

Это мой код, который загружает файл в s3 с помощью API высокого уровня AWS.

        ClientConfiguration configuration = new ClientConfiguration();
        configuration.setUseGzip(true);
        configuration.setConnectionTTL(1000 * 60 * 60);
        AmazonS3Client amazonS3Client = new AmazonS3Client(configuration);
        TransferManager transferManager = new TransferManager(amazonS3Client);

        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(message.getBodyLength());
        objectMetadata.setContentType("image/jpg");

        transferManager.getConfiguration().setMultipartUploadThreshold(1024 * 10);

        PutObjectRequest request = new PutObjectRequest("test", "/image/test", inputStream, objectMetadata);
        request.getRequestClientOptions().setReadLimit(1024 * 10);
        request.setSdkClientExecutionTimeout(1000 * 60 * 60);

        Upload upload = transferManager.upload(request);
        upload.waitForCompletion();

Я пытаюсьзагрузить большой файл.Это работает правильно, но иногда я получаю ошибку ниже.Я установил readLimit как (1024 * 10).

2019-04-05 06:41:05,679 ERROR [com.demo.AwsS3TransferThread] (Aws-S3-upload) Error in saving File[media/image/osc/54/54ec3f2f-a938-473c-94b7-a55f39aac4a6.png] on S3[demo-test]: com.amazonaws.ResetException: Failed to reset the request input stream;  If the request involves an input stream, the maximum stream buffer size can be configured via request.getRequestClientOptions().setReadLimit(int)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.resetRequestInputStream(AmazonHttpClient.java:1221)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1042)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:948)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:661)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:635)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:618)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$300(AmazonHttpClient.java:586)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:573)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:445)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4041)
    at com.amazonaws.services.s3.AmazonS3Client.doUploadPart(AmazonS3Client.java:3041)
    at com.amazonaws.services.s3.AmazonS3Client.uploadPart(AmazonS3Client.java:3026)
    at com.amazonaws.services.s3.transfer.internal.UploadCallable.uploadPartsInSeries(UploadCallable.java:255)
    at com.amazonaws.services.s3.transfer.internal.UploadCallable.uploadInParts(UploadCallable.java:189)
    at com.amazonaws.services.s3.transfer.internal.UploadCallable.call(UploadCallable.java:121)
    at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:139)
    at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:47)

Какова цель readLimit?Как это будет полезно?Что я должен сделать, чтобы избежать такого исключения?

1 Ответ

1 голос
/ 18 апреля 2019

После изучения этой проблемы в течение 1 недели я обнаружил, что если размер загружаемого вами файла меньше 48 ГБ, вы можете установить значение readLimit 5,01 МБ.

, поскольку AWS делит файл на несколько частей и размер каждой части.Значение равно 5 МБ (если вы не изменили значение минимального размера детали).Согласно спецификации AWS размер последней части составляет менее 5 МБ.поэтому я установил readLimit 5 МБ, и это решает проблему.

InputStream readLimit цель:

Отмечает текущую позицию в этом входном потоке.Последующий вызов метода сброса перемещает этот поток в последнюю отмеченную позицию, так что последующие операции чтения перечитывают те же байты. Аргументы Readlimit сообщают этому входному потоку, что необходимо прочитать много байтов до того, как позиция метки будет признана недействительной.Общий контракт mark заключается в том, что, если метод markSupported возвращает, поток каким-то образом запоминает все байты, прочитанные после вызова mark, и готов снова предоставить те же байты, если и когда будет вызван метод reset.Однако поток не обязан запоминать какие-либо данные вообще, если перед вызовом сброса из потока читается больше байтов readLimit.

...