【问题标题】:Java AmazonS3 putObject fails silentlyJava AmazonS3 putObject 静默失败
【发布时间】:2020-10-09 22:28:52
【问题描述】:

其他人在没有收到答案的情况下发布了这个问题,现在我遇到了同样的问题。实际上它已经持续了 9 个月,但我现在才注意到它。

此序列不抛出异常,并记录最后的消息:

AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
String bucket = "...";
String key = "...";
File f = new File("...");
PutObjectResult r = s3.putObject(bucket, key, f);
String etag = r.getETag();
LOGGER.info("file ... saved with etag = "+etag);

当我查看时,该文件不在存储桶中。

在发布的数千个文件中,每天都会失败几十次。有 25 个活动线程使用此代码序列。 aws-java-sdk 线程安全吗?其他想法?

这是在亚马逊云中的一个 ec2 实例上运行的。

详情:

aws-java-sdk-s3-1.11.693.jar
java: 1.8.0_201-b09
ubuntu: 4.4.0-1077-aws

【问题讨论】:

  • “这个序列不会抛出异常,并且会记录最后的消息。” 听起来不可能。我对 Java 的了解不够,甚至无法使用正确的术语,但线程必须仍在运行、阻塞、等待某些东西,不是吗?它不能失败到日志行,也不会抛出异常。您是否泄漏/丢失了线程?我的观点是,“静默失败”似乎是对您正在经历的事情的不准确描述,因为之后线程的状态是什么,以及该日志行是如何被跳过的?相反,这听起来像是“挂起”状态。
  • 字面意思是执行日志语句并写入日志条目,并且该文件在存储桶中不存在。这就是我知道它不会引发异常的方式。因此,短语“默默地失败”。
  • 哇,我需要学习阅读。我错误地看到最后的消息是 not logged ...所以“静默失败”是正确的。
  • 为您的存储桶开启日志记录,看看幕后发生了什么。
  • The docs 说:“Amazon S3 从不存储部分对象;如果在此调用期间未引发异常,则存储整个对象”。所以,我认为,有两个问题:1)您要上传的文件是否存在?它有内容吗? 2)它到底是在哪里实际应用的?打印putObject 结果并仔细研究它的内容。

标签: java amazon-s3 aws-java-sdk


【解决方案1】:

我在使用 AmazonS3.putObject 上传 27MB 文件时看到了这个问题。该命令返回了PutObjectResult,但预期位置没有 S3 对象,结果元数据 (result.getMetadata().getContentLength()) 显示 0 字节。我通过使用 this link 的分段上传解决了这个问题。

private static final Logger LOGGER = LoggerFactory.getLogger(S3Handler.class);
private static final long MAX_SINGLE_PART_UPLOAD_BYTES = 5 * 1024 * 1024;

private final AmazonS3 amazonS3;

public S3Handler(AmazonS3 amazonS3) {
    this.amazonS3 = amazonS3;
}

public void putS3Object(String bucket, String objectKey, File file) {
    if (file.length() <= MAX_SINGLE_PART_UPLOAD_BYTES) {
        putS3ObjectSinglePart(bucket, objectKey, file);
    } else {
        putS3ObjectMultiPart(bucket, objectKey, file);
    }
}

private void putS3ObjectSinglePart(String bucket, String objectKey, File file) {
    PutObjectRequest request = new PutObjectRequest(bucket, objectKey, file);
    PutObjectResult result = amazonS3.putObject(request);
    long bytesPushed = result.getMetadata().getContentLength();
    LOGGER.info("Pushed {} bytes to s3://{}/{}", bytesPushed, bucket, objectKey);
}

private void putS3ObjectMultiPart(String bucket, String objectKey, File file) {
    long contentLength = file.length();
    long partSize = MAX_SINGLE_PART_UPLOAD_BYTES;
    List<PartETag> partETags = new ArrayList<>();

    // Initiate the multipart upload.
    InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucket, objectKey);
    InitiateMultipartUploadResult initResponse = amazonS3.initiateMultipartUpload(initRequest);

    // Upload the file parts.
    long fileOffset = 0;
    for (int partNumber = 1; fileOffset < contentLength; ++partNumber) {
        // Because the last part could be less than 5 MB, adjust the part size as needed.
        partSize = Math.min(partSize, (contentLength - fileOffset));

        // Create the request to upload a part.
        UploadPartRequest uploadRequest = new UploadPartRequest()
                .withBucketName(bucket)
                .withKey(objectKey)
                .withUploadId(initResponse.getUploadId())
                .withPartNumber(partNumber)
                .withFileOffset(fileOffset)
                .withFile(file)
                .withPartSize(partSize);

        // Upload the part and add the response's ETag to our list.
        UploadPartResult uploadResult = amazonS3.uploadPart(uploadRequest);
        LOGGER.info("Uploading part {} of Object s3://{}/{}", partNumber, bucket, objectKey);
        partETags.add(uploadResult.getPartETag());

        fileOffset += partSize;
    }

    // Complete the multipart upload.
    CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucket, objectKey, initResponse.getUploadId(), partETags);
    amazonS3.completeMultipartUpload(compRequest);
}

【讨论】:

    猜你喜欢
    • 2019-07-19
    • 2012-01-11
    • 2017-01-10
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多