Spring Boot Amazon S3 Bucket大文件上传

utugiqy6  于 2023-10-16  发布在  Spring
关注(0)|答案(4)|浏览(144)

我试图上传一个CSV文件的约5 Mb大小到亚马逊S3使用low-level api使用java SDK。
我在下面提到的错误:.
com.amazonaws.services.s3.model.AmazonS3Exception:指定的上载不存在。上载ID可能无效,或者上载可能已中止或完成。(服务:Amazon S3;验证码:错误代码:NoSuchUpload;请求ID:)
你能告诉我哪里出了问题吗?我使用的是us-west-1区域。

List<PartETag> partETags = new ArrayList<PartETag>();
    InitiateMultipartUploadRequest initRequest = new 
    InitiateMultipartUploadRequest(tempVariableBucketName, tempVariableAccessKey);
    InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest);

    long contentLength = is.available();
    long partSize = 1 * 1024 * 1024; // Set part size to 1 MB.

    try {
        long filePosition = 0;
        for (int i = 1; filePosition < contentLength; i++) {
            partSize = Math.min(partSize, (contentLength - filePosition));
            logger.info("Upload Id " + initResponse.getUploadId());
            UploadPartRequest uploadRequest = new UploadPartRequest()
                .withBucketName(tempVariableBucketName).withKey(fileName)
                .withUploadId(initResponse.getUploadId()).withPartNumber(i)
                .withFileOffset(filePosition)
                .withInputStream(is)
                .withPartSize(partSize);

            partETags.add(s3Client.uploadPart(uploadRequest).getPartETag());
            filePosition += partSize;
        }
        CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(tempVariableBucketName,tempVariableAccessKey,initResponse.getUploadId(),partETags);
        s3Client.completeMultipartUpload(compRequest);
    } catch (Exception e) {
        logger.error(e.getMessage());
        s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(tempVariableBucketName, tempVariableAccessKey, initResponse.getUploadId()));
        throw e;
    }
dwthyt8l

dwthyt8l1#

Pleas make sure our AWS S3 configuration :
     <CORSConfiguration>
        <CORSRule>
            <AllowedOrigin>*</AllowedOrigin>
            <AllowedMethod>GET</AllowedMethod>
            <MaxAgeSeconds>3000</MaxAgeSeconds>
            <AllowedHeader>Authorization</AllowedHeader>
        </CORSRule>
    </CORSConfiguration>
efzxgjgh

efzxgjgh2#

你的一个上传失败了。您需要从s3Client.uploadPart()捕获错误并重试。
我建议对下面的简单代码进行以下改进。
1)为每次重试添加递增的超时。
2)处理错误类型以确定重试是否有意义。对于某些错误,您应该报告错误并中止。
3)将重试次数限制在10次左右,以防止永远的while循环。

// repeat the upload until it succeeds.
boolean anotherPass;  
    do {
          anotherPass = false;  // assume everythings ok
          try {
              // Upload part and add response to our list.
              partETags.add(s3Client.uploadPart(uploadRequest).getPartETag());
          } catch (Exception e) {
                anotherPass = true; // repeat
          }
    } while (anotherPass);

这个堆栈溢出问题有代码来改进你的例子的错误处理。
Problems when uploading large files to Amazon S3

ezykj2lf

ezykj2lf3#

试试AWS Team https://docs.aws.amazon.com/AmazonS3/latest/userguide/CopyingObjectsMPUapi.html的建议
在使用上面的示例代码之前,也要在pom.xml中添加dependecy:

<dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-s3</artifactId>
         <!-- please use the latest version available -->
        <version>1.12.470</version>
    </dependency>

它的工作就像一个魅力!...

h4cxqtbf

h4cxqtbf4#

我使用AWS的GeneratePresignedUrlRequest功能解决了这个问题。但是现在我得到了一个新的错误。413请求实体太大nginx。我在谷歌上搜索了解决方案,我发现我需要在服务器的nginx.conf文件中进行更改。现在问题来了,因为我将有多个服务器/负载均衡器示例,所以,我必须手动设置它为每个示例?

相关问题